反射,就是应用Class纪录的类信息来完成类的实例化,方法调用,参数调用。与我们正常操作对象方法是不同的。
反射应用到了以下这几种类:Class,Constructor,Filed,Method,想熟练掌握反射就要先掌握这些类。下面举几个反射基本应用的例子。
首先了解下Class类。第个类都有对应的Class类实例(即字节码),里面纪录了该类的构造器,方法,属性信息。
字节码的获取方式有3种(以String为例):
a.Class string = String.class //类名.class
b. String a = "abc";Class string = a.getClass();//对象.getClass()
c.Class string = Class.forName("java.lang.String");//Class.forName(类的全名)
例1:利用Constructor实例化对象
public static void constructorTest () throws Exception{
Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
String str1 = (String)constructor.newInstance(new StringBuffer("abc"));//注意参数要和获得的构造器相对应
System.out.println(str1);
}
例2:利用Method类取得属性值
public static void methodTest() throws Exception{
String str ="abc";
Method charAt = String.class.getMethod("charAt", int.class);
System.out.println(charAt.invoke(str, 2));
}
注意:假设String有个静态方法为staticMethod(int i),则有
Method staticMethod = String.class.getMethod("staticMethod",int.class);
staticMethod.invoke(null,2);//静态方法第一个参数为null,因为第一个参数是指操作的对象
例3:利用Field类取得属性值,特别注意私有属性如何取
Person类:
public class Person {
public String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
操作私有属性 需要先调用setAccessible(boolean flag)方法将可访问级别设置可以访问即可。
public static void filedTest() throws Exception{
Person p = new Person("linhan",25);
Field name= Person.class.getField("name");
System.out.println(name.get(p));
Field age = Person.class.getDeclaredField("age");// age属性的私有所以不能用上面的方法
age.setAccessible(true);//取得访问权限
System.out.println(age.get(p));
age.set(p, 26);//设置属性值
System.out.println(age.get(p));
}