Java类的初始化
来源:互联网 发布:暴风vr电视直播软件 编辑:程序博客网 时间:2024/05/29 02:32
大家都知道类的初始化顺序,有父类的时候,顺序是:
–> 父类的静态成员(包括静态变量和静态代码块)
–> 子类的静态成员(包括静态变量和静态代码块)
–> 父类的普通成员(普通成员变量和普通代码块)和构造函数
–> 子类的普通成员(普通成员变量和普通代码块)和构造函数
我个人觉得大家平时说的初始化可以分成两类,也即两个阶段,首先是类的初始化,其次是对象的初始化。静态成员初始化属于类初始化,普通成员和构造函数初始化属于对象初始化。
原因如下示例:
class H { static int s = 1; static { System.out.println("first static block"); System.out.println("ordinary var s initial: " + s); s = 2; System.out.println("ordinary var s afer change: " + s); } public int a; { System.out.println("first ordinary block"); System.out.println("ordinary var a : " + a); } static { System.out.println("last static block " + s); } public H() { System.out.println("constructor"); } { System.out.println("last ordinary block"); }}
在main函数里
new H();new H();
则运行结果如下
//静态成员first static blockordinary var s initial: 1ordinary var s afer change: 2last static block 2//普通成员first ordinary blockordinary var a : 0last ordinary block//构造函数constructor//普通成员first ordinary blockordinary var a : 0last ordinary block//构造函数constructor
代码就不细讲了,很明显可以看到,在两次创建对象的过程中,静态成员初始化了一次,对象成员(姑且这么叫先)初始化两次。当然,类静态变量存放在方法区,实例变量存在于类对象对应的堆内存中,每创建一个对象就在堆内存开辟一个内存区域存放对象成员等内容,所以也就很明白了。
我要说的是另外一个值得注意的地方,就是Class.forName(String name)方法。Class.forName()方法返回的是一个类(Class对象),作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段。
在main函数里调用该方法
try { Class.forName("H"); } catch (ClassNotFoundException e) { e.printStackTrace(); }
则运行结果如下
//静态成员first static blockordinary var s initial: 1ordinary var s afer change: 2last static block 2
只有类静态成员初始化了。
JDK文档里是这样说的:
A call to forName("X") causes the class named X to be initialized.
另外,还有一个类加载方法forName(String name, boolean initialize, ClassLoader loader),根据参数名称就可以理解参数的含义,其中第二项参数就是确定是否需要初始化类。
那么在其他函数里这样调用(因为有this关键字不能在静态的main方法里用):
try { //initialize = false Class.forName("H",false,this.getClass().getClassLoader()); } catch (ClassNotFoundException e) { e.printStackTrace();}
运行后什么也没有显示,即没有进行类的初始化工作,但是没有抛异常,说明类已经加载完成了,估计连接也已经完成。
再测试如下,创建实例对象:
try { Class<?> c = Class.forName("H",false,this.getClass().getClassLoader()); c.newInstance();} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { e.printStackTrace();}
则运行结果如下
//静态成员first static blockordinary var s initial: 1ordinary var s afer change: 2last static block 2//普通成员first ordinary blockordinary var a : 0last ordinary block//构造函数constructor
与 new H();
是一样的效果。
参考
Class.forName
Java初始化顺序
- java 类的初始化
- java 类的初始化
- java类的初始化
- Java类的初始化
- JAVA类的初始化
- Java类的初始化
- java 类的初始化
- Java类的初始化
- Java类的初始化
- java类的初始化
- Java类的初始化
- Java类的初始化
- Java类的初始化
- java 类的初始化
- Java类的初始化
- java类的初始化
- java类的初始化
- java 类的初始化
- 初识贪心:POJ2393--Yogurt factory
- Juicer 中文文档
- 简便使用命令行跑脚本
- listView刷新单个Item
- POJ2996Help Me with the Game
- Java类的初始化
- PHP函数之error_reporting
- CF703D. Mishka and Interesting sum
- EventBus3.0,使用过程中所有的梗。
- 区分使用Axis2和CXF的wsdl2java命令
- Mysql CPU占用高的问题解决方法小结
- hdu 5615 (Jam's math problem)
- 手机号码正则表达式js校验
- Android手机悬浮窗口小例子