反射机制
31.1概述
反射:允许对成员变量、成员方法、构造方法的信息进行编程访问。
也就是通过反射可以获取类里面的所有信息.
31.2 获取class对象
- Class.forName(“全类名”)
- 类名.class
- 对象.getClass( );
public class StudentTest {
public static void main(String[] args) throws ClassNotFoundException {
// Class.forName("全类名")
Class<?> aClass = Class.forName("flect.test01.Student");
System.out.println(aClass);
//class flect.test01.Student
// 类名.class
Class<Student> stuClass = Student.class;
System.out.println(stuClass);
//class flect.test01.Student
// 对象.getClass( );
Student stu = new Student();
Class<? extends Student> aClass1 = stu.getClass();
System.out.println(aClass1);
//class flect.test01.Student
System.out.println(aClass1 == aClass);//true
System.out.println(aClass == stuClass);//true
}
}
31.3 反射获取构造方法
Class类中用于获取构造方法的方法
Constructor<?>[] getConstructors() 返回所有公共构造方法对象的数组
Constructor<?>[] getDeclaredConstructors() 返回所有构造方法对象的数组
Constructor<T> getConstructor(Class<?>... parameterTypes) 返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
返回单个构造方法对象
Constructor类中用于创建对象的方法
T newInstance(Object... initargs) 根据指定的构造方法创建对象
setAccessible(boolean flag) 设置为true,表示取消访问检查
public class Student {
private String name;
private int age;
public Student() {}
public Student(String name) {this.name = name;}
protected Student(int age) {this.age = age;}
private Student(String name, int age) {
this.name = name;
this.age = age;
}
......
@Override
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
===============
public class Test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//1.获取class字节码文件对象
Class clazz = Class.forName("flect.test02.Student");
//2.1获取构造方法,
// 返回所有公共(public 修饰的)构造方法对象的数组
Constructor[] cons1 = clazz.getConstructors();
for (Constructor con : cons1) {
System.out.println(con);
//public flect.test02.Student(java.lang.String)
// public flect.test02.Student()
}
// 2.2获取构造方法
// 返回所有构造方法对象的数组(public private protected修饰的)
Constructor[] cons2 = clazz.getDeclaredConstructors();
for (Constructor con : cons2) {
System.out.println(con);
}
// 3.返回单个构造方法对象
Constructor cons3 = clazz.getDeclaredConstructor();
System.out.println(cons3);
//public flect.test02.Student()
Constructor cons4 = clazz.getDeclaredConstructor(String.class);
System.out.println(cons4);
//private flect.test02.Student(java.lang.String,int)
Constructor cons5 = clazz.getDeclaredConstructor(String.class, int.class);
System.out.println(cons5);
//private flect.test02.Student(java.lang.String,int)
// 4.获取权限修饰符对应的常量字段值
int modifiers = cons5.getModifiers();
System.out.println(modifiers);//2
// 5.获取所有参数
Parameter[] parameters = cons5.getParameters();
for (Parameter parameter : parameters) {
System.out.println(parameter);
}
//暴力反射:表示临时取消权限校验
cons5.setAccessible(true);
// 创建学生对象(私有)
Student stu =(Student) cons5.newInstance("张三", 18);
System.out.println(stu);
}
}
31.4 反射获取成员变量
Class类中用于获取成员变量的方法
Field[] getFields(): 返回所有公共成员变量对象的数组
Field[] getDeclaredFields() 返回所有成员变量对象的数组
Field getField(String name) 返回单个公共成员变量对象
Field getDeclaredField(String name) 返回单个成员变量对象
Field类中用于创建对象的方法
void set(Object obj, Object value):赋值
Object get(Object obj) 获取值
public class Student {
private String name;
private int age;
public String gender;
public Student() {}
public Student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
@Override
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
====================================
public class StudetTest {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
//1.获取class字节码文件的对象
Class<?> clazz = Class.forName("flect.test03.Student");
System.out.println(clazz);
// 2.1获取所有的成员变量
Field[] fields = clazz.getDeclaredFields();
for (Field fiefld : fields) {
System.out.println(fiefld);
}
// 2.1获取所有公共的成员变量
Field[] fields1 = clazz.getFields();
for (Field field : fields1) {
System.out.println(field);
}
//获取单个的成员变量
Field name = clazz.getDeclaredField("name");
System.out.println(name);
//private java.lang.String flect.test03.Student.name
//获取权限修饰符
int modifiers = name.getModifiers();
System.out.println(modifiers);//2
//获取成员变量的名字
String name1 = name.getName();
System.out.println(name1);//name
//获取成员变量的数据类型
Class<?> type = name.getType();
System.out.println(type);
//class java.lang.String
//获取成员变量记录的值
Student s = new Student("zhangsan",23,"男");
name.setAccessible(true);
// Object value = (String) name.get(s);
String value = (String) name.get(s);
System.out.println(value);
//修改对象里面记录的值
name.set(s,"lisi");
System.out.println(s);
}
}