反射
通过Class获取字节 码文件对象,使用字节码文件对象来获取类的一些描述信息
一. 获取字节码文件对象
- 方式有三种:
1.Object的getClass方法
Student s1 = new Student();
Student s2 = new Student();
Class<? extends Student> class1 = s1.getClass();
Class<? extends Student> class2 = s2.getClass();
System.out.println(class1==class2);//结果为true
2.通过数据类型的静态属性 class属性
Class<?> c1=Student.class;
System.out.println(c1==class1);//结果为true
3.Class类中一个静态方法
Properties pro = new Properties();
pro.load(new FileReader(new File("pro.txt")));
Class<?> class3=Class.forName(pro.getProperty("studentName"));
System.out.println(class3==c1);//结果为true
二.反射获取构造方法并且创建对象
- 获取方法:
1.Constructor<?>[] getConstructors() // 获取公有修饰的构造方法对象
Constructor<?>[] constructors = c.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
2.Constructor<?>[] getDeclaredConstructors() // 获取所有的构造方法对象
Constructor<?>[] Constructors1 = c.getDeclaredConstructors();
for (Constructor<?> constructor2 : Constructors1) {
System.out.println(constructor2);
}
3.Constructor getConstructor(Class<?>… parameterTypes) //获取指定的公有修饰的构造方法对象
Constructor<?> constructor4 = c.getConstructor(String.class,Integer.class,int.class,int.class,int.class);
4.Constructor getDeclaredConstructor(Class<?>… parameterTypes) //获取指定的构造方法对象,包括私有
Constructor<?> declaredConstructor = c.getDeclaredConstructor(String.class,Integer.class);
System.out.println(declaredConstructor);
- 创建方法
1.获取字节码文件对象
2.通过字节码文件对象获取构造方法对象
3.通过构造方法对象创建对象 : T newInstance(Object… initargs)
Class<?> c = Class.forName(value);
Constructor<?> con = c.getConstructor();
//获取无参构造方法
Object obj = con.newInstance();
System.out.println(obj);
Student student = (Student) obj;
System.out.println(student.getName());
// 调用带全参数
Constructor<?> constructor = c.getConstructor(String.class, int.class);
Object obj2 = constructor.newInstance("隔壁老王", 50);
System.out.println(obj2);
// 获取私有构造方法并且造对象
Constructor<?> constructor2 = c.getDeclaredConstructor(String.class);
// 暴力访问
constructor2.setAccessible(true);//修改访问权限修饰符
Object obj3 = constructor2.newInstance("隔壁老李");
System.out.println(obj3);
三.反射获取成员变量对象并且赋值
- 获取方法
1.Field[] getFields() 获取公有修饰的成员变量对象,包括父类的公有成员
Class<?> c = Class.forName("com.sdas.reflectdemo3.Student");
Field[] fields2 = c.getFields();
for (Field field : fields2) {
System.out.println(field);
}
2.Field[] getDeclaredFields() 获取所有本类的成员,包括私有
Class<?> c = Class.forName("com.sdas.reflectdemo3.Student");
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
3.Field getField(String name) 获取指定的公共成员变量对象
Field field = c.getField("address");
System.out.println(field);
4.Field getDeclaredField(String name) 获取公有的成员属性,包括父类
System.out.println(c.getDeclaredField("name"));
- 赋值方法
set(obj, value)
Class<?> c = Class.forName("com.so.reflect.Student");
Field nameField = c.getDeclaredField("age");//获取指定成员变量
Constructor<?> con = c.getDeclaredConstructor();//获取无惨构造方法
Object instance = con.newInstance();
//nameField.setAccessible(true);若成员变量为私有,需修改权限修饰符
nameField.set(instance, 15);
System.out.println(nameField.get(instance));
四.反射获取成员方法对象并且调用
- 成员方法
1.getMethods() :获取所有公有方法 包括父类继承过来的成员
2.getDeclaredMethods() 获取本类中所有方法,包括私有
3.Method getMethod(String name, Class<?>… parameterTypes)
4.Method getDeclaredMethod(String name, Class<?>… parameterTypes)
第一个参数是方法名称, 第二个参数是参数类型列表
Class<?> c = Class.forName("com.st.reflectdemo4.Student");
Constructor<?> con = c.getDeclaredConstructor();
Object obj = con.newInstance();
// 获取无参方法show并且调用
Method method = c.getDeclaredMethod("show");
System.out.println(method);
method.invoke(obj);
System.out.println("--------------------------");
// public void method(String s) 共有有参
Method method2 = c.getDeclaredMethod("method", String.class);
System.out.println(method2);
method2.invoke(obj, "Hello");
System.out.println("--------------------------");
// public String concat(int a, String s, double d) 共有多参
Method method3 = c.getDeclaredMethod("concat", int.class, String.class, double.class);
System.out.println(method3);
Object result = method3.invoke(obj, 20, "张三", 2.5);
System.out.println(result);
System.out.println("--------------------------");
//private void show2() 私有无参
Method method4 = c.getDeclaredMethod("show2");
method4.setAccessible(true);
System.out.println(method4);
method4.invoke(obj);
// int getModifiers() 获取方法权限名称
int modifiers = method4.getModifiers();
System.out.println(modifiers);