java.lang.Class
- Java程序运行时,Java运行时系统一直对所有的对象进行运行时类型识别。这项信息记录了每个对象所属的类。虚拟机通常使用运行时类型信息选择正确方法去执行,用来保存这些类型信息的类是Class类。Class类封装一个对象和接口运行时状态,当装载类时,Class类型的对象就自动创建。
- Class没有公共构造方法。Class对象是在加载类时由JVM以及通过调用类加载器中的defineClass方法自动构造的,因此不能显示声明一个Class对象。
- JVM为每种类型管理一个独一无二的Class对象。也即是,每个类都有一个Class对象。运行程序时,JVM首先检查要加载的类其对应的Class对象是否已经加载。如果没有加载,JVM就根据类名查找.class文件,将其Class对象载入。
- Java的基本类型(boolean,byte,char,int…)和void也都对应一个Class对象。一般某个类的Class对象被载入内存,它就用来创建这个类的所有对象。
Class.forName 与 new
- Class.forName() JVM会查找并加载指定的类,并执行类的静态代码。
- 从JVM角度看,使用new创建一个类时候,这个类可以没有加载。但是使用newInstance()方式时候,就必须保证:1.这个类已经加载。2.这个类已经连接了。而完成上面两步真是Class.forName()所完成的,会调用启动类加载器。
public class TestClass {
public static void main(String[] args) {
try {
// 测试Class.forName()
System.out.println("testForName before");
Class testTypeForName = Class.forName("TestClassType");
System.out.println("testForName--" + testTypeForName);
// 测试类名。class
Class testTypeClass = TestClassType.class;
System.out.println("testTypeClass--" + testTypeClass);
// 测试Object.getClass()
TestClassType testGetClass = new TestClassType();
System.out.println("testGetClass--" + testGetClass.getClass());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class TestClassType {
// 构造函数
public TestClassType() {
System.out.println("--构造函数--");
}
// 静态的参数初始化
static {
System.out.println("--静态的参数初始化--");
}
// 非静态的参数初始化
{
System.out.println("--非静态的参数初始化--");
}
}
运行结果
testForName before
--静态的参数初始化--
testForName--class TestClassType
testTypeClass--class TestClassType
--非静态的参数初始化--
--构造函数--
testGetClass--class TestClassType
调用顺序
类加载时
1. 静态代码在类被加载时执行
通过new得到类实例时
1. 非静态代码执行
2. 构造函数执行