一、什么是反射?
1.1 Class
类
一个特殊的类型。
public final class Class {
private Class() {}
}
由JVM在第一次读取到一种
class
类型时,将其加载进内存。每加载一种class
,JVM就为其创建一个Class
类型的实例,并关联起来。JVM持有的每个Class
实例都指向一个数据类型(class
或interface
)。
1.2 反射
由于JVM为每个加载的class
创建了对应的Class
实例,并在实例中保存了该class
的所有信息,包括类名、包名、父类、实现的接口、所有方法、字段等,因此,如果获取了某个Class
实例,我们就可以通过这个Class
实例获取到该实例对应的class
的所有信息。
这种通过**Class**
实例获取**class**
信息的方法称为反射(**Reflection**
)。
1.3 如何获取一个class
的Class
实例?
直接通过一个class的静态变量class获取
Class cls = String.class;
通过该实例变量提供的getClass()方法获取
String s = "Hello";
Class cls = s.getClass();
```java public class Hi { public static void main(String[] args) {
Class cls = Person.class;
System.out.println(cls.getName());
for (var meth : cls.getMethods()) {
System.out.println(meth);
}
} }
class Person { private String age; private String name;
public void setAge(String age) {this.age = age;}
public String getAge() {return age;}
public void setName(String name) {this.name = name;}
public String getName() {return name;}
}
// Person // public java.lang.String Person.getName() // public void Person.setName(java.lang.String) // public void Person.setAge(java.lang.String) // public java.lang.String Person.getAge() // public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException // public final void java.lang.Object.wait() throws java.lang.InterruptedException // public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException // public boolean java.lang.Object.equals(java.lang.Object) // public java.lang.String java.lang.Object.toString() // public native int java.lang.Object.hashCode() // public final native java.lang.Class java.lang.Object.getClass() // public final native void java.lang.Object.notify() // public final native void java.lang.Object.notifyAll()
- 如果知道一个class的完整类名,可以通过静态方法Class.forName()获取
```java
Class cls = Class.forName("java.lang.String");
1.4 动态加载
JVM在执行Java程序的时候,并不是一次性把所有用到的class全部加载到内存,而是第一次需要用到class时才加载。
二、作用
2.1 获取字段
一个实例,只要我们获取了它的Class
,就可以获取它的一切信息。
public class Hi {
public static void main(String[] args) {
Class cls = Person.class;
System.out.println(cls.getName());
for (var item : cls.getDeclaredFields()) {
System.out.println(item);
}
}
}
class Person {
private String age;
private String name;
public void setAge(String age) {this.age = age;}
public String getAge() {return age;}
public void setName(String name) {this.name = name;}
public String getName() {return name;}
}
// Person
// private java.lang.String Person.age
// private java.lang.String Person.name