当我们编写一个新的java类时,JVM就会帮我们编译成class对象,存放在同名的.class文件中。
在运行时,当需要生成这个类的对象,JVM就会检查此类是否已经装载内存中。
若是没有装载,则把.class文件装入到内存中。若是装载,则根据class文件生成实例对象。
每个类的class对象只有一个,实例对象可以有多个
把该类名.class文件装载入JVM即是生成类的class对象,
静态的参数初始化在生成类的class对象时运行,即当前JVM中暂无class对象,
需要把该类名.class文件装载入JVM,在一次运行期间只装载一次,所以每个类的class对象只有一个
非静态的参数初始化 和 构造函数 在生成类的实例对象时运行
装载=生成class对象
!=运行静态的参数初始化
!=运行非静态的参数初始化
静态的参数初始化,是在装载类时运行。而非静态的参数初始化,是new类的实例对象时运行。
装载类时不一定都运行静态的参数初始化。
生成class对象不一定运行静态的参数初始化
Class.class只进行类装载,不进行类的静态的参数初始化
Class.forname()进行类的转载和静态的参数初始化
object.class进行类的转载、静态的参数初始化、非静态的参数初始化和构造函数
一般某个类的Class对象被载入内存,它就用来创建这个类的所有对象。
Class对象的生成方式如下:
1.Class.forName("类名字符串"),包括包名
2.Class.class
3.object.getClass()
通过一段小程序,来观察一下Class对象的生成的原理。
public class Main {
public static void main(String[] args) {
Class testTypeForName = null;
try {
testTypeForName = Class.forName("TestClassType");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("测试Class.forName(),testForName---" + testTypeForName);
System.out.println("#############################################################");
Class testTypeClass = TestClassType.class;
System.out.println("测试Class.class,testTypeClass---" + testTypeClass);
System.out.println("#############################################################");
TestClassType testGetClass = new TestClassType();
System.out.println("测试Object.getClass(),testGetClass---" + testGetClass.getClass());
}
}
class TestClassType {
//构造函数
public TestClassType() {
System.out.println("----构造函数---");
}
//静态的参数初始化
static {
System.out.println("---静态的参数初始化---");
}
//非静态的参数初始化
{
System.out.println("----非静态的参数初始化---");
}
}
三种同时运行:
---静态的参数初始化---
测试Class.forName(),testForName---class TestClassType
#############################################################
测试Class.class,testTypeClass---class TestClassType
#############################################################
----非静态的参数初始化---
----构造函数---
测试Object.getClass(),testGetClass---class TestClassType
//前面测试Class.forName()时已把该类名.class文件装载入JVM,所以现在不需再次装载,所以不再运行静态的参数初始化
分别运行一种:
---静态的参数初始化---
测试Class.forName(),testForName---class TestClassType
//只生成class对象,进行类装载和静态的参数初始化,没有new生成实例对象,所以非静态的参数初始化 和 构造函数不运行
#############################################################
测试Class.class,testTypeClass---class TestClassType
#############################################################
//只生成class对象,只进行类装载,不进行静态的参数初始化
---静态的参数初始化---
----非静态的参数初始化---
----构造函数---
测试Object.getClass(),testGetClass---class TestClassType
//生成class对象和实力对象,前面没有把该类名.class文件装载入JVM,即还没有class对象,所以需要先装载一次,并且运行静态的参数初始化,
//然后生成实例对象,会运行非静态的参数初始化 和 构造函数
参考:
http://blog.sina.com.cn/s/blog_76ecd078010178pe.html
http://blog.csdn.net/zhangxichao100/article/details/51104971
http://blog.csdn.net/yuebinghaoyuan/article/details/7244123