一、反射的定义
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象,也就是要获取到该类的Class对象。
二、获取Class对象的三种方式
// 第一种,调用对象的getClass()方法
Person person = new Person();
Class<?> personClass1 = person.getClass();
Person p1 = (Person) personClass1.newInstance();
p1.test();
// 第二种,调用类的class静态属性。
Class<?> personClass2 = Person.class;
Person p2 = (Person) personClass2.newInstance();
p2.test();
// 第三种,使用Class类的forName(String clazzName)静态方法。传入参数是某个类的全限定名
Class<?> personClass3 = Class.forName("com.zcs.study.reflection.Person");
Person p3 = (Person) personClass3.newInstance();
p3.test();
三、通过Class对象获取类的信息
(1)获取类的属性
Person person = new Person();
Class<?> personClass = person.getClass();
//获取所有的属性,包括私有属性
Field[] declaredFields = personClass.getDeclaredFields();
Arrays.stream(declaredFields).forEach(System.out::println);
System.out.println();
//获取所有的public的属性
Field[] fields = personClass.getFields();
Arrays.stream(fields).forEach(System.out::println);
System.out.println();
//获取指定的属性,包括私有属性
System.out.println(personClass.getDeclaredField("sex"));
System.out.println();
//获取指定的public的属性
System.out.println(personClass.getField("name"));
System.out.println();
(2)获取构造函数
// 获取所有的构造函数,包括私有的构造函数
Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
Arrays.stream(declaredConstructors).forEach(System.out::println);
System.out.println();
// 获取所有的public的构造函数
Constructor<?>[] constructors = personClass.getConstructors();
Arrays.stream(constructors).forEach(System.out::println);
System.out.println();
// 获取指定的构造函数,包括私有的构造函数
Constructor<?> declaredConstructor =
personClass.getDeclaredConstructor(String.class, int.class, String.class, String.class);
declaredConstructor.setAccessible(true);
Person person1 = (Person) declaredConstructor.newInstance("zcs", 20, "男", "address test");
System.out.println(person1.toString());
/// 获取指定的public的构造函数
Constructor<?> constructor = personClass.getConstructor(String.class);
Person person2 = (Person) constructor.newInstance("zcs");
System.out.println(person2);
(3)获取普通方法和静态方法
// 获取所有的方法,包括私有方法
Method[] declaredMethods = personClass.getDeclaredMethods();
Arrays.stream(declaredMethods).forEach(System.out::println);
System.out.println();
// 获取所有的public的方法
Method[] methods = personClass.getMethods();
Arrays.stream(methods).forEach(System.out::println);
System.out.println();
// 获取指定的public的方法
Method nameMethod = personClass.getMethod("printName", String.class);
nameMethod.invoke(personClass.newInstance(), "zcs");
// 获取指定的方法,包括私有方法
Method ageMethod = personClass.getDeclaredMethod("printAge", int.class);
ageMethod.setAccessible(true);
ageMethod.invoke(personClass.newInstance(), 18);
// 获取指定的public static方法
Method publicStaticMethod = personClass.getMethod("publicStaticPrint");
publicStaticMethod.invoke(null);
// 获取指定的private static方法
Method privateStaticMethod = personClass.getDeclaredMethod("privateStaticPrint", String.class);
privateStaticMethod.setAccessible(true);
privateStaticMethod.invoke(null, "zcs");
Person类
public class Person {
public String name;
public int age;
private String sex;
private String address;
public Person() {}
private Person(String name, int age, String sex, String address) {
this.name = name;
this.age = age;
this.sex = sex;
this.address = address;
}
public Person(String name) {
this.name = name;
}
private Person(int age) {
this.age = age;
}
public void printName(String name) {
System.out.println("This is printName method for " + name);
}
private void printAge(int age) {
System.out.println("This is printAge method for " + age);
}
public static void publicStaticPrint() {
System.out.println("This is publicStaticPrint method");
}
public static void privateStaticPrint(String name) {
System.out.println("This is privateStaticPrint method for " + name);
}
public void test() {
System.out.println("This is a test for Person class.");
}
}
还有很多其他的操作,有兴趣的可以自己研究。