Java反射机制:
是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意方法和属性;
这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制;
利用反射可以无视修饰符获取类里面所有的属性和方法。
先获取配置文件中的信息,动态获取信息并创建对象和调用方法。
利用反射调用它类中的属性和方法时,无视修饰符。
获取Class类的对象:
获取class对象三种方式:
获取CLASS对象的方式 | 作用 |
---|---|
类名.class | 通过类名的属性class获取 |
Class.forName(“类全名”) | 通过指定的字符串路径获取 |
对象.getClass() | 通过对象的getClass()方法获取 |
// 1.Class类中的静态方法forName("全类名")
Class clazz = Class.forName("reflect.Student");
System.out.println(clazz);
// 2.通过class属性来获取
Class clazz2 = Student.class;
System.out.println(clazz2);
// 3.利用对象getClass方法来获取
// getClass方法是定义在Object类中
Student student = new Student();
Class clazz3 = student.getClass();
System.out.println(clazz3);
一个类中可以把成员变量认为成员变量对象:Field
构造方式认为构造方法对象:Constructor
成员方法认为成员方法对象:Method
反射获取构造方法对象:
对象.getConstructors() | 获取所有public对象 | 返回一个数组[] |
---|---|---|
对象.getDeclaredConstructors() | 获取所有public、private对象 | 返回一个数组[] |
对象.getConstructor() | 返回单个public构造方法对象,()里需要和构造方法保持一致 | 返回构造方法对象 |
对象.getDeclaredConstructor() | 获取私有的private构造方法,()里需要和构造方法保持一致 | 返回构造方法对象 |
// 1、获取class对象
Class clazz = Class.forName("reflect.Student2");
// 2、获取所有公共的构造方法
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
// 3、获取所有构造方法,private+public
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
// 4、获取单个public构造方法,有参构造获取需要和构造方法保持一致
Constructor constructor = clazz.getConstructor();
System.out.println(constructor);
Constructor constructor1 = clazz.getConstructor(String.class, int.class);
System.out.println(constructor1);
// 5、获取单个私有构造方法,有参构造获取需要和构造方法保持一致
Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
System.out.println(declaredConstructor);
反射获取构造方法并使用:
构造方法对象.newInstance(参数) | 用于创建一个对象 | |
---|---|---|
ps:如果需要使用私有方法创建对象必须用私有构造方法对象.setAccessible(true);临时取消访问检查
// 1、获取class对象
Class clazz = Class.forName("reflect.Student");
// 2、获取构造方法对象,有参构造
Constructor constructor = clazz.getConstructor(String.class, int.class);
//3、利用newInstance创建Student对象
Student student = (Student) constructor.newInstance("zhangsan", 23);
System.out.println(student);
// 无参构造创建
// 1、获取class对象
Class clazz = Class.forName("reflect.Student2");
Student student = (Student) clazz.newInstance();
System.out.println(student);
// 私有构造方法创建对象
// 1、获取class对象
Class clazz = Class.forName("reflect.Student2");
// 2、获取一个私有构造方法
Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
// 3、被私有的构造方法不能直接创建对象,如果需要使用,必须用私有构造方法.setAccessible(true);临时取消访问检查
declaredConstructor.setAccessible(true);
// 4、创建对象
Student2 student = (Student2) declaredConstructor.newInstance("张三");
System.out.println(student);
获取成员变量(Field)对象:
类对象.getFields(); | 获取所有public成员变量对象 |
---|---|
类对象.getDeclaredFields(); | 获取所有成员变量对象(包括私有变量) |
类对象.getField(“变量名”); | 返回单个公共的成员变量 |
类对象.getDeclaredField(“变量名”); | 获取单个私有成员变量 |
// 1、获取class对象
Class clazz = Class.forName("reflect.StudentDemo");
// 2、获取所有public成员变量对象
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field);
}
// 3、获取所有成员变量对象
Field[] Fields = clazz.getDeclaredFields();
for (Field field : Fields) {
System.out.println(field);
}
// 4、返回单个公共的成员变量
Field field = clazz.getField("name");
System.out.println(field);
// 5、获取单个私有成员变量
Field field2 = clazz.getDeclaredField("money");
System.out.println(field);
反射获取成员变量并使用
变量对象.set(对象,变量) | 使用变量对象.set,参数一传入一个实例对象,参数二传入需要保存的值 |
---|---|
变量对象.get(对象) | 获取对象变量值 |
// 1、创建class对象
Class clazz = Class.forName("com.edu.info.ReflectDemo.Student");
// 2、获取成员变量
Field field = clazz.getField("name");
// 3、创建对象
Student student = (Student) clazz.newInstance();
// 4、set赋值
field.set(student,"zhangsan");
System.out.println(student);
-----------------------------------
// 1、创建class对象
Class clazz = Class.forName("com.edu.info.ReflectDemo.Student");
// 创建变量对象
Field field = clazz.getDeclaredField("money");
// 设置允许临时访问
field.setAccessible(true);
// 创建类实例对象
Student student = (Student) clazz.newInstance();
// 根据变量对象查询值
Object o = field.get(student);
System.out.println(o);
获取成员方法:
clazz.getMethods(); | 获取所有公共成员方法,包括继承的父类 |
---|---|
clazz.getDeclaredMethods(); | 获取所有成员方法,不包括父类 |
clazz.getMethod(“function1”); | 获取一个指定的公共成员方法 |
clazz.getMethod(“function2”, String.class); | 获取一个指定的公共方法,带参数的 |
clazz.getDeclaredMethod(“show”); | 获取一个私有方法 |
Class clazz = Class.forName("com.edu.info.ReflectDemo.Student2");
// 1.获取所有公共成员方法,包括继承的父类
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}
// 2.获取所有成员方法,不包括继承的
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
// 3.获取一个指定的公共成员方法
Method method = clazz.getMethod("function1");
System.out.println(method);
// 4.获取一个指定的公共方法,带参数的
Method method = clazz.getMethod("function2", String.class);
System.out.println(method);
// 5.获取一个私有方法
Method method = clazz.getDeclaredMethod("show");
System.out.println(method);
反射回去成员方法并运行
Object invoke(Object obj,Objcet…args):运行方法
参数一:用obj对象调用该方法
参数二:调用方法穿的的参数(没有则不写)
返回值 :方法的返回值(没有则不写)
// 1、创建class对象
Class clazz = Class.forName("com.edu.info.ReflectDemo.Student2");
// 2、获取method对象
Method method = clazz.getMethod("function4", String.class);
// invoke参数一需要调用者对象,所有创建student对象
Student2 student = (Student2) clazz.newInstance();
// 参数一调用对象,参数二形参,用result接受返回值,没有返回值则不用接收
Object result = method.invoke(student, "zhangsan");
System.out.println(result);