反射:在运行状态下,通过class文件对象,去使用构造方法,成员变量,成员方法
获取class文件(字节码对象)
方式1 通过Object类的getClass方法
Person p = new Person();
Class c1 = p.getClass();
Person p2 = new Person();
Class c2 = p2.getClass();
System.out.println(p == p2);
System.out.println(c1 == c2); //true 一个类的字节码对象只有一个
方式2 任意对象的静态的class属性
Class c3 = Person.class;
方式3 通过Class类的静态方法forName()
Class c4 = Class.forName("com.reflect.Person");
反射获取构造方法
- Constructor[] Class.getConstructors() : 返回公共构造方法
- Constructor[] Class.getDeclaredConstructors() : 返回所有构造方法(包含私有)
- Constructor Class.getConstructor() : 可变参数,此处获取无参构造方法
- Constructor.newInstance() :构造器创建对象
//1.获取字节码文件对象
Class c = Class.forName("com.reflect.Person");
//2.获取构造器对象
// Constructor[] cons = c.getConstructors(); //返回公共构造方法
// for(Constructor con:cons){
// System.out.println(con);
// }
// cons = c.getDeclaredConstructors(); //返回所有构造方法(包含私有)
// for(Constructor con:cons){
// System.out.println(con);
// }
Constructor con = c.getConstructor(); //可变参数,此处获取无参构造方法
System.out.println(con);
Constructor con2 = c.getConstructor(String.class, int.class);//获取带参构造函数
System.out.println(con2);
//3.通过构造器对象创建对象
Object obj = con.newInstance();
System.out.println(obj);
Object obj2 = con2.newInstance("xyg", 24);
System.out.println(obj2);
反射获取成员变量
- Field[] Class.getFields() : 获取Public成员变量
- Field[] Class.getDeclaredFields() : 获取所有成员变量(包括私有)
- Field Class.getField(String) : 获取单个成员变量
- Field Class.getDeclaredField(String) : 获取单个私有成员
//1.获取字节码对象
Class c = Class.forName("com.reflect.Person");
//2.获取成员变量对象
Field[] fields = c.getFields();//获取Public成员变量
for(Field f:fields){
System.out.println(f);
}
System.out.println("----");
fields = c.getDeclaredFields();//获取所有成员变量
for(Field f:fields){
System.out.println(f);
}
Field ageField = c.getField("age");//获取单个成员变量
Field nameField = c.getDeclaredField("name");//获取单个私有成员
nameField.setAccessible(true);//设置为true才能访问
//3.通过Field对象设置成员值
Constructor con = c.getConstructor();
Object obj = con.newInstance(); //构造器构造对象
ageField.set(obj, 12);//给obj对象的field字段赋值12
nameField.set(obj, "xyg");
System.out.println(obj);
反射获取类成员方法
- Method[] Class.getMethods() : 获取所有公共方法,包括父类方法
- Method[] Class.getDeclaredMethods() : 获取本类的所有方法(不包括父类)
- Method Class.getMethod() : 获取单个方法,无参传递null
- Method Class.getDeclaredMethod() : 获取私有方法
//1.获取字节码对象
Class c = Class.forName("com.reflect.Person");
Constructor con = c.getConstructor();
Object obj = con.newInstance();
//2.获取方法
Method[] methods = c.getMethods();//获取所有公共方法,包括父类方法
for(Method m:methods){
System.out.println(m);
}
System.out.println("-----");
methods = c.getDeclaredMethods();//获取本类的所有方法(不包括父类)
for(Method m:methods){
System.out.println(m);
}
Method m1 = c.getMethod("show", null);//获取单个无参方法
m1.invoke(obj, null);//无参传递null
Method m2 = c.getMethod("function", String.class);//获取单个有参方法
m2.invoke(obj, "xyg");
Method m3 = c.getMethod("returnValue", String.class,int.class);//夺取多参有返回值
System.out.println(m3.invoke(obj, "林青霞",38));
Method m4 = c.getDeclaredMethod("hello",null);//获取私有方法
m4.setAccessible(true);//设置为true
m4.invoke(obj, null);
应用
使用反射越过泛型jianc
ArrayList<Integer> list = new ArrayList<>();
list.add(24);
list.add(432);
// list.add("fdjsl");ERROR
Class c = list.getClass();
Method m = c.getDeclaredMethod("add", Object.class);//这里要接受Object的字节码
m.invoke(list, "hello");
m.invoke(list, "world");
System.out.println(list);