java反射机制(一)—— 利用反射机制实例化对象
一、Java有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。(度娘文库是这么说的)
二、这篇文章主要介绍一下通过反射机制去实例化一个类的对象,然后调用其方法。本文主要介绍两种方式,第一种就是通过构造函数来实例化,第二种就是通过Class<T>类的newnstance()方法进行实例化,下面我就通过代码来展示:
1、首先我建了一个Person类作为测试用的:
package com.reflect.test; /** * @author 林楷鹏 * @description 测试用的 * @create 2014-11-27下午9:34:00 * */ public class Person { private int age; private String name; public Person() { } public Person(String name) { this.name = name; } public Person(int age, String name) { this.age = age; this.name = name; } public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public String getName() { return name; } }
2、通过构造函数:
package com.reflect.test; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @author 林楷鹏 * @description 反射机制,通过构造函数实例化对象 * @create 2014-11-27下午9:32:05 * */ public class ReflectConstructor { public static void main(String[] args) { Person person = new Person(); try { Class<?> cls = Class.forName(person.getClass().getName()); //参数类型 Class<?>[] params = {Integer.TYPE, String.class}; //参数值 Object[] values = {15, "kroc"}; //构造有两个参数的构造函数 Constructor<?> constructor = cls.getDeclaredConstructor(params); //根据构造函数,传入值生成实例 Object object = constructor.newInstance(values); Method getAge = cls.getDeclaredMethod("getAge"); Method getName = cls.getDeclaredMethod("getName"); System.out.println("getAge = " + (Integer)getAge.invoke(object)); System.out.println("getName = " + (String)getName.invoke(object)); } catch (ClassNotFoundException e) { e.printStackTrace(); System.out.println("ClassNotFoundException"); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }可以看到代码中,以下两行是比较重要的,第一行是通过参数个数去获取一个构造函数,记得这里传的参数的个数和类型要跟Person里面构造函数里面的相符,而参数类型也要和参数值values的类型一样,我这里就封装成params和values一起传进去
//构造有两个参数的构造函数 Constructor<?> constructor = cls.getDeclaredConstructor(params); //根据构造函数,传入值生成实例 Object object = constructor.newInstance(values);
运行结果如下:
3、第二种方式是通过Class<T>类的newnstance()方法进行初始化:
package com.reflect.test; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @author 林楷鹏 * @description 反射机制,通过newInstance()实例化对象 * @create 2014-11-27下午9:41:01 * */ public class ReflectMethod { public static void main(String[] args) { Person person = new Person(); try { Class<?> cls = Class.forName(person.getClass().getName()); //生成实例,调用默认无参构造函数 Object object = cls.newInstance(); Method setName = cls.getDeclaredMethod("setName", String.class); Method setAge = cls.getDeclaredMethod("setAge", Integer.TYPE); setName.invoke(object, "KrocLin"); setAge.invoke(object, 20); Method getAge = cls.getDeclaredMethod("getAge"); Method getName = cls.getDeclaredMethod("getName"); System.out.println("getAge = " + (Integer)getAge.invoke(object)); System.out.println("getName = " + (String)getName.invoke(object)); } catch (ClassNotFoundException e) { e.printStackTrace(); System.out.println("ClassNotFoundException"); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }代码可以知道,其实用newInstance()是调用Person的默认无参构造函数的,所以本质上还是跟上一种方式一样。
运行结果:
三、关于反射机制,可以做的事情还有很多,上面我为了简单展示就类似于getName这些方法名什么的都写死了,其实还可以通过反射去获取方法名,包括方法的返回类型啊、抛出异常等等都可以通过反射机制去得到。以后有时间就再写一些关于java反射机制的文章分享下,对于这个如果哪里写错了或者有什么更好的建议麻烦评论交流。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。