1、在程序运行过程中,可以对任意一个类型进行任意的操作。例如:加载任意类型、调用类型的任意方法、获取任意的成员变量、构造方法,可以创建该类型的对象。
2、如果要获取一个类型的各种内容,首先要获取这个类的字节码对象,解剖这个类型,获取类中的成员,需要使用Class类型中定义的方法。
3、反射就是这种动态的获取信息以及动态的访问成员的方式,称为反射。
4、获取类的字节码文件的三种方式
public class Test{ public static void main(String[] args) throws Exception { Student stu = new Student(); //第一种方法:通过对象名.getClass() Class class1 = stu.getClass(); //第二种方法:类名.class Class class2 = Student.class; //第三种方法:Class.forName(全类名) Class class3 = Class.forName("com.test1.Student"); System.out.println(class1==class2); System.out.println(class1==class3); } } class Student{ private String name; int age; private void run() { System.out.println("run run run"); } public void setName(String name) { this.name = name; } public Student(String name, int age) { super(); this.name = name; this.age = age; } public Student() {} }
5、反射常用方法代码示例
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Test1 { public static void main(String[] args) throws Exception { Student stu = new Student(); Class class1 = stu.getClass(); //获取到的.class文件.getField(属性名)获取属性 //getFields获取所有属性到一个数组中 Field f1 = class1.getDeclaredField("age"); //可以设置属性 System.out.println(stu.age); f1.set(stu, 15); System.out.println(stu.age); //上面的方式无法得到私有属性,需要暴力反射 Field f2 = class1.getDeclaredField("name"); //暴力反射也分getDeclaredField()和getDeclaredFields(),原理同getFiled和getFileds //想要设置私有属性必须使用setAccessible()将里面的参数设为true f2.setAccessible(true); System.out.println(stu); f2.set(stu, "qq"); System.out.println(stu); //获取构造方法getConstructor(构造方法里的参数类型.class) 返回一个Constructor构造器 //这个构造器可以使用newInstance() 创建一个object类型的对象 Constructor c = class1.getConstructor(String.class,int.class); Object obj = c.newInstance("bb",10); Student stu2 = (Student)obj; System.out.println(stu2); //同理,构造器也有getConstructors和暴力反射 //获取成员方法getMethod(方法名, 参数.class) Method m1 = class1.getMethod("setName",String.class); //方法的使用,方法.invoke(对象名,参数) m1.invoke(stu2, "hh"); System.out.println(stu2); //同理,有getMethods和暴力反射getDeclaredMethod... Method m2 = class1.getDeclaredMethod("run",null); //同理需要设置权限 m2.setAccessible(true); m2.invoke(stu); } } class Student{ private String name; int age; private void run() { System.out.println(name+"run run run"); } public void setName(String name) { this.name = name; } public Student(String name, int age) { super(); this.name = name; this.age = age; } public Student() {} @Override public String toString() { return name+"..."+age; } }