- 反射概述
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;同时也能调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 我们通过一个类的字节码文件获取到他的所有信息。
(图->itheima)
2.反射的常用操作
1.获取Class对象(反射永远的第一步操作)
2.反射调用对象中的成员方法
3.反射调用对象中的构造方法
4.反射调用对象中的属性
在此之前定义一个student类
public class Student { private String name; Integer age; public String address; public Student(){} public Student(String name,Integer age,String address){ this.name=name; this.age=age; this.address=address; } private Student(String name){ this.name=name; } Student(String name,Integer age){ this.name=name; this.age=age; } private void function(){ System.out.println("function"); } public void method1(){ System.out.println("method"); } public void method2(String s){ System.out.println("method:"+s); } public String method3(String s, Integer i){ return s+","+i; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", address='" + address + '\'' + '}'; } }
- 获取Class对象
三种方法可以获得Class
1.使用类的Class属性来获取该类对应的Class对象。
2.调用Object的getClass()方法,返回该对象所属类对应的Class对象
3.使用Class类中的静态方法forName(String className) 该方法的参数,该字符串参数的值 是某个类的全路径
第三种是最为推荐的
直接上代码:
//使用类的Class属性来获取该类对应的Class对象。 //.class是字节码文件 Class<Student> student = Student.class; Class<Student> student1=Student.class; System.out.println(student); System.out.println(student==student1); //调用对象的getClass()方法,返回该对象所属类对应的Class对象 Student student2=new Student(); Class<? extends Student> student21 = student2.getClass(); System.out.println(student21==student); //使用Class类中的静态方法forName(String className) 该方法的参数,该字符串参数的值是某个类的全路径 Class<?> student3 = Class.forName("com.ReflectTest.Student"); System.out.println(student3==student);
结果:
所以一个类的Class对象是相同的,因为他们的字节码文件是唯一的
- 反射调用对象中的成员变量
1.getDeclaredField(参数) 返回某一个成员变量
2.getFields() 返回所有公开的成员变量 返回类型为数组
3.getField() 返回某一个公开的成员变量
4.getDeclaredFields(参数) 返回所有的成员变量 返回类型为数组
(同下,大家都是聪明人就不一一测试了)
//获取Class类 Class<?> student = Class.forName("com.ReflectTest.Student"); //获取一个公共的成员变量 Field field = student.getField("address"); //给address赋值 //1.获取对象 Constructor<?> con = student.getConstructor(); //2.初始化实例 Object o = con.newInstance(); //3.使用field对象赋值 field.set(o,"武汉"); System.out.println(o);
- 反射调用对象中的构造方法
1.getDeclaredConstructor(参数) 返回某一个构造方法
2.getConstructors() 返回所有公开的构造方法 返回类型为数组
3.getConstructor() 返回某一个公开的构造方法
4.getDeclaredConstructors(参数) 返回所有的构造方法 返回类型为数组
直接上代码:
//获取Class对象 Declared是所有的 没有Declared为公共的 Class<?>student=Class.forName("com.ReflectTest.Student"); //getConstructor(类<?>... parameterTypes) 返回一个 Constructor对象,返回单个公共构造方法对象 //newInstance(Object... initargs) 使用此 Constructor对象表示的构造函数,使用指定的初始化参数来创建和初始化构造函数的声明类的新实例。 //根据Constructor创建con1(带三个参数的公共构造方法对象) Constructor<?> con1 = student.getConstructor(String.class, Integer.class, String.class); Object o = con1.newInstance("猪猪侠",17,"弗洛伊德"); System.out.println(o); System.out.println(con1); System.out.println("---"); //getConstructors() 返回包含一个数组 Constructor对象,返回所有公共构造方法对象的数组 Constructor<?>[] con2 = student.getConstructors(); for (Constructor con : con2) { System.out.println(con); } System.out.println("---"); //getDeclaredConstructor(类<?>... parameterTypes) 返回一个 Constructor对象,返回单个构造方法对象 Constructor<?> con3 = student.getDeclaredConstructor(); System.out.println(con3); System.out.println("---"); //getDeclaredConstructors() 返回一个反映 Constructor对象,返回所有构造方法对象的数组 Constructor<?>[] con4 = student.getDeclaredConstructors(); for (Constructor con : con4) { System.out.println(con); }
结果:
反射构造对象时 需初始化newInstance
若构造方法为私有的,还需要调用setAccessible(true)来取消访问检查
//获取Class类 Class<?>student=Class.forName("com.ReflectTest.Student"); //反射获取一个private方法的反射对象 Constructor<?> con = student.getDeclaredConstructor(String.class); //private的构造方法无法创建对象 需要赋予权限 //setAccessible 值为true 取消访问检查 //newInstance 初始化实例 con.setAccessible(true); Object o = con.newInstance("林青霞"); System.out.println(o);
![]()
- 反射调用对象中的成员方法
同上 方法改为
1.getDeclaredMethod(参数) 返回某一个成员方法
2..... 3.... 4....
//获取Class字节码文件 Class<?> pra = Class.forName("com.ReflectTest.Student"); //1.反射获得student对象 Constructor<?> con = pra.getDeclaredConstructor(); //2.对象的初始化 Object o = con.newInstance(); //3.通过对象调用method1方法 //先反射获得method1方法 Method method1 = pra.getDeclaredMethod("method1"); method1.invoke(o); System.out.println("-----"); //4.通过对象调用method2方法 Method method2 = pra.getDeclaredMethod("method2", String.class); method2.invoke(o,"林青霞"); System.out.println("-----");
see you!