概念
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
class类
Class类是一个比较特殊的类,它是反射机制的基础,Class类的对象表示正在运行的Java程序中的类或接口,也就是任何一个类被加载时,即将类的.class文件(字节码文件)读入内存的同时,都自动为之创建一个java.lang.Class对象。Class类没有公共构造方法,其对象是JVM在加载类时通过调用类加载器中的defineClass()方法创建的,因此不能显式地创建一个Class对象。通过这个Class对象,才可以获得该对象的其他信息。下表列出了Class类的一些常用方法。
要使用反射,要先获取class类
建立一个Person类作为实验对象
public class Person {
private String name;
private String address;
public int age;
public Person() {
}
public Person(String name) {
this.name = name;
}
public Person(String name, String address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public void show(){
System.out.println("Person中show方法被调用");
}
}
获取class对象
//反射获取class对象 首先要先获取.class文件,字节码文件
public static void getClass1(){
try {
//在代码编写阶段获取
Class class1 = Class.forName("com.hu.reflect.Person");
System.out.println("代码编写阶段:"+class1);
System.out.println("=======================================");
//在字节码阶段获取
Class<Person> personClass = Person.class;
System.out.println("在字节码阶段:"+personClass);
System.out.println("=======================================");
//在虚拟机运行阶段获取
Person p = new Person();
Class pClass = p.getClass();
System.out.println("在虚拟机运行阶段:"+pClass);
System.out.println("=======================================");
System.out.println(class1==personClass);
System.out.println(class1==pClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
获取构造方法并实例化对象
//反射获取构造方法并实例化对象
public static void getConstructor1(){
Class<Person> personClass = Person.class;
//获得全部构造方法
Constructor<?>[] constructors = personClass.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
System.out.println("=======================================");
//获取指定的构造方法
try {
Constructor<Person> constructor1 = personClass.getConstructor();//通过指定的参数来确定构造方法,此处为无参
System.out.println(constructor1);
Person person = constructor1.newInstance();//相当于Person p = new Person()
person.show();//方法能被调用,说明实例化成功
System.out.println("=======================================");
Constructor<Person> constructor = personClass.getConstructor(String.class);//通过指定的参数来确定构造方法
System.out.println(constructor);
Person huge = constructor.newInstance("huge");//相当于Person p = new Person("huge")
//这个地方相当于调用了构造方法
System.out.println(huge.getName());
System.out.println(huge.getAddress());
huge.show();//方法能被调用,说明实例化成功
} catch (Exception e) {
e.printStackTrace();
}
}
获取普通方法并操作
//反射获取普通方法并操作
public static void getMethod1(){
Person person = new Person();
Class personClass = person.getClass();
//getMethods()获取的是本类及其父类所有的公共方法
Method[] method = personClass.getMethods();
for (Method method1 : method) {
System.out.println(method1);
}
System.out.println("=======================================");
//getDeclaredMethods()获取的是本类所有的公共方法
Method[] declaredMethods = personClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
System.out.println("=======================================");
//调用具体的方法并执行
try {
//获取无参的普通方法,反射中调用invoke()执行方法
Method m1 = personClass.getDeclaredMethod("show");
m1.invoke(person);
//获取有参的方法执行
Method m2 = personClass.getDeclaredMethod("setName", String.class);
m2.invoke(person,"huge");
//查看是否执行成功
System.out.println(person.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
获取成员变量并操作
//反射获取成员变量并操作
public static void getFiled1() {
try {
Class pClass = Class.forName("com.hu.reflect.Person");
System.out.println(pClass);
//只能获取公共成员变量
Field[] fields = pClass.getFields();
for (Field field : fields) {
System.out.println(field.toString());
}
System.out.println("=======================================");
//可以获取私有成员变量(包括公共成员变量)
Field[] declaredFields = pClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField.toString());
}
System.out.println("=======================================");
//newInstance()方法是调用默认的构造方法实例化一个对象
Object p = pClass.newInstance();
//根据名字获取公有成员变量并操作
Field age1 = pClass.getDeclaredField("age");
System.out.println(age1);
//用set方法来设置值
age1.set(p,18);
//用get方法来获取值
System.out.println(age1.get(p));
System.out.println("=======================================");
//根据名字获取私有成员变量,需要将暴力破解
Field name1 = pClass.getDeclaredField("name");
System.out.println(name1);
//需将这个值设置为true才能操作私有变量
name1.setAccessible(true);
name1.set(p,"huge");
System.out.println(name1.get(p));
} catch (Exception e) {
e.printStackTrace();
}
}