反射实际使用
1,反射生成类实例对象
a,生成类的实例对象有零种方式
- 使用Class对象的newInstance()方法来创建该对象对应类的实例。(前提是这种方式要求该Class对象一定有默认的构造器,而执行newInstance()方法时实际上是利用默认构造器来创建该类的实例)
- 先使用Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建Class对象对应类的实例。通过这种方式可以选择指定的构造器来创建实例。
b,New 对象和反射获取对象的区别
- 在使用反射的时候,必须确保这个类已经加载。而使用New 的时候,这个类可以没有被加载,也可以已经被加载。
- New关键字可以调用任何public构造方法,而反射只能调用无参构造方法。
- New关键字是强类型,效率相对较高。反射是弱类型的,效率低。
- 反射提供了一种跟家灵活的方式创建对象,得到对象的信息。如动态代理的使用,都是基于反射的。解耦。
例如:
//获取Class对象==>Class.forName() Class<?> aClass = Class.forName("gpatmobile.tunion.com.myReflect.Person"); //获取类实例对象的第一种方式 Person o = (Person) aClass.newInstance(); //获取类实例对象的第二种方式 Constructor<?>[] constructors = aClass.getConstructors(); for (int i = 0; i < constructors.length; i++) { System.out.println("构造函数:" + constructors[i]); } Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(); Person o1 = (Person) declaredConstructor.newInstance(); System.out.println("单个构造方法:" + aClass.getConstructor()); Person o2 = (Person) aClass.getConstructor().newInstance(); System.out.println("单个构造方法:" + aClass.getDeclaredConstructor(String.class, String.class)); Person o3 = (Person) aClass.getDeclaredConstructor(String.class, String.class).newInstance("yhl", "29"); |
2,反射调用类的方法
a,通过Class对象的getMethods()方法或者getMethod()方法获得指定方法,返回Method数组或对象。
b,调用Method对象中的Object invoke(Object obj ,Object …args)方法。第一个参数对应
//获取Class对象==>Class.forName() Class<?> aClass = Class.forName("gpatmobile.tunion.com.myReflect.Person"); Person o3 = (Person) aClass.getDeclaredConstructor(String.class, String.class).newInstance("yhl", "29"); //第一种方式:调用person类中getname() String name = o3.getName(); System.out.println("name==" + name); //第二种方式:获得与该方法对应的Method对象 Method setAge = aClass.getDeclaredMethod("setAge", String.class); //设置权限 setAge.setAccessible(true); //调用指定的方法并传递参数 setAge.invoke(o3,"26"); String age = o3.getAge(); System.out.println("age==" + age); |
调用该方法的实例对象,第二个参数对应该方法的参数。
注意:当通过Method的invoke()方法来调用对应的方法时,Java会要求程序必须有调用该方法的权限。如果程序确实需要调用某个对象的private方法,则可以先调用Method对象的如下方法。setAccessible(boolean flag):将Method对象的acessible设置为指定的布尔值。值为true,指示该Method在使用时应该取消Java语言的访问权限检查;值为false,则知识该Method在使用时要实施Java语言的访问权限检查。
3,反射访问成员变量值
a,通过Class对象的getFields()方法或者getField()方法获得指定方法,返回Field数组或对象。
b,Field提供了两组方法来读取或设置成员变量的值:getXXX(Object obj):获取obj对象的该成员变量的值。此处的XXX对应8种基本类型。如果该成员变量的类型是引用类型,则取消get后面的XXX。getXXX(Object obj):获取obj对象的该成员变量的值。此处的XXX对应8种基本类型。如果该成员变量的类型是引用类型,则取消get后面的XXX。