反射概述
Java的反射机制是指在程序的运行状态中,可以构造任意一个类的对象,可以得到任意一个对象所属类的信息,可以调用任意一个类的成员变量和方法,可以任意获取任意一个对象的属性和方法。这种动态获取程序信息和动态调用对象的功能就成为Java语言的反射机制。
认识Class类
Class类的使用
1)Class对象的获取
Class c1 = TestClass.class:
b.根据对象获取:对象.getClass()
Class c1 = new TestClass.getClass
Class的几种获取方式
(1)获取类的java.lang.Class实例对象,常见的三种方式分别为:
通过MyClass.class获取,这里的MyClass指具体类~~
通过Class.forName("类的全局定名")获取,全局定名为包名+类名
通过new MyClass().getClass()获取,这里的MyClass指具体类~
(2)通过MyClass.class获取,JVM会使用ClassLoader类加载器将类加载到内存中,但并不会做任何类的初始化工作,返回java.lang.Class对象
(3)通过Class.forName("类的全局定名")获取,同样,类会被JVM加载到内存中,并且会进行类的静态初始化工作,返回java.lang.Class对象
(4)通过new MyClass().getClass()获取,这种方式使用了new进行实例化操作,因此静态初始化和非静态初始化工作都会进行,getClass方法属于顶级Object类中的方法,任何子类对象都可以调用,哪个子类调用,就返回那个子类的java.lang.Class对象
PS: 这3种方式,最终在JVM堆区对应类的java.lang.Class对象都属于同一个,也就是内存地址相同,进行==双等号比较结果为true,原因是JVM类加载过程中使用的是同一个ClassLoader类加载器加载某个类,不论加载多少次,生成到堆区的java.lang.Class对象始终只有一个,除非自定义类加载器,破坏JVM的双亲委派机制,使得同一个类被不同类加载器加载,JVM才会把它当做两个不同的java.lang.Class对象
创建一个实体类,分别在实体类中创建类的静态代码块
、动态代码块
、有参构造方法
、无参构造方法
,方便测试几种方式的区别及内存地址是否相同~
(1)实体类:
public class MyClass {
private static final String staticStr = "Hi";
private static int staticInt = 2021;
private String id;
static {
System.out.println("静态代码块:staticStr=" + staticStr + ",staticInt=" + staticInt);
}
{
System.out.println("动态代码块~");
}
public MyClass() {
System.out.println("无参构造方法~");
}
public MyClass(String id) {
System.out.println("有参构造方法~");
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return "MyClass{" +
"id='" + id + '\'' +
'}';
}
}