^_^散分了~~顺便纠正一个容易犯的小错误^_^
静态块里的代码不一定是第一次被加载时执行,
确切的说应该是第一次实例化的时候执行~
因为他的执行和类的加载方式有关:
看看下面的:
1,测试类:
package com.daniel.test;
public class TestStatic {
static{
System.out.println( "执行静态块! ");
}
public void print(){
System.out.println( "执行TestStatic.print()! ");
}
}
2,主类:
package com.daniel.test;
public class StaticTest {
public static void main(String[] args) throws Exception {
StaticTest st = new StaticTest();
System.out.println( "准备加载com.daniel.test.TestStatic... ");
Class clazz = st.getClass().getClassLoader().loadClass( "com.daniel.test.TestStatic ");
System.out.println( "加载com.daniel.test.TestStatic成功! ");
System.out.println( "准备实例化com.daniel.test.TestStatic... ");
TestStatic ts = (TestStatic)clazz.newInstance();
System.out.println( "实例化com.daniel.test.TestStatic成功! ");
ts.print();
}
}
3,执行结果:
准备加载com.daniel.test.TestStatic...
加载com.daniel.test.TestStatic成功!
准备实例化com.daniel.test.TestStatic...
执行静态块!
实例化com.daniel.test.TestStatic成功!
执行TestStatic.print()!
从结果很明显看出:
静态块的执行是类第一次实例化的时候进行的~~~~~
而 不是 大家常说的第一次加载类的时候执行的!!!!!
[解决办法]
此加载非彼加载...
[解决办法]
没看明白,冲着分来的
看似楼上的明白呀
[解决办法]
实例化跟加载功能上一样吧
别钻牛角尖
[解决办法]
lz的理解是对的
[解决办法]
支持楼主!
帮楼主找到了一个理论依据:在 Java Language Specification 中找到这样一句“Any static initializers declared in a class are executed when the class is initialized”,也就是说,并不是在“加载(loadClass)”的时候,而是在“initialized”的时候。
至于什么时候是“initialized”,也不难找到,用如下代码就能清楚地看到了:
static{
System.out.println( "执行静态块! ");
Throwable t = new Throwable();
t.printStackTrace();
}
[解决办法]
实例化跟加载功能上并不一样,虽然大多数的Java虚拟机采用的lazy loading的方式,也就是当一个类第一次需要被实例化的时候才会从磁盘读取byte code加载类,不过这不是必然,有时候为了特殊原因,比如加密或者完整性检查,可以先加载所有用到的类,然后慢慢实例化,或者Java虚拟机直接就这么做了。楼主共享的经验,不顶是不行的。
[解决办法]
接分
[解决办法]
JF
[解决办法]
jf
[解决办法]
mark!
[解决办法]
学习
[解决办法]
jf 学习
------解决方案--------------------
接分
[解决办法]
jf
[解决办法]
不顶不行
[解决办法]
jf
[解决办法]
学习
[解决办法]
接分!
[解决办法]
接分
[解决办法]
恭喜,接分
[解决办法]
接分
[解决办法]
接分
[解决办法]
jf
[解决办法]
接分
[解决办法]
接分
[解决办法]
jf
[解决办法]
jf
[解决办法]
接分
[解决办法]
接分
[解决办法]
jf
[解决办法]
有没搞错
自己打自己的脸
确切的说,是第一次初始化的时候执行,而不是第一次实例化的时候执行
比如一个你前面forName测试的例子,即使不实例化,还是会输出静态初始化块的运行结果
[解决办法]
接分啦!
同时学习!
[解决办法]
daniel_kaka() ( ) 信誉:100 Blog 加为好友 2007-4-20 0:07:43 得分: 0
代码上已经很明白~
难道这点代码都看不懂吗!
代码上已经明确的说明了什么是加载,什么是实例化!!
这个帖子不是讨论什么事实例化什么事加载!!
而是要说明一个事实:
static静态块
是在类第一次实例化的时候执行的;
而不是在类刚加载的时候执行的!
看到这我只想举个例子出来说明一下,即类的静态块不是在类被第一次实例化时才执行的
class Test {
static int a=0;
static {
System.out.println( "ABC ");
}
Test() {
System.out.println(a + " } ");
}
}
public class Ttest{
public static void main(String args[]) {
Test.a=10;
}
}
结果是
ABC
我想已经很明白了吧,这个例子里面并没有把Test类实例化吧。
[解决办法]
接分
[解决办法]
学习了,接分
[解决办法]
接分了,呵呵
[解决办法]
顶楼主
[解决办法]
hehe, 现在已经有三个概念了:
类加载
类初始化 <-- 这里会执行静态初始化代码
实例化
这样是不是清楚一点了 ;->
[解决办法]
学习
[解决办法]
楼主好像概念混淆了
现在手头有任务,等晚点说
[解决办法]
为分而来
[解决办法]
,接分
[解决办法]
为分而来
[解决办法]
get scores ……
[解决办法]
JF
[解决办法]
期待各位大师的讨论
[解决办法]
静态块里的代码不一定是第一次被加载时执行,
确切的说应该是第一次实例化的时候执行~
不对吧?
好象是第一次被加载时执行
[解决办法]
jf
[解决办法]
楼主的观点充满了错误:
把你的代码稍改一下:
package com.daniel.test;
public class TestStatic {
static{
System.out.println( "执行静态块! ");
}
public void print(){
System.out.println( "执行TestStatic.print()! ");
}
//这是我加的
public static void printStatic(){
System.out.println( "执行TestStatic.printStatic()! ");
}
}
2,主类:
package com.daniel.test;
public class StaticTest {
public static void main(String[] args) throws Exception {
TestStatic.printStatic();//这是我加的
StaticTest st = new StaticTest();
System.out.println( "准备加载com.daniel.test.TestStatic... ");
Class clazz = st.getClass().getClassLoader().loadClass( "com.daniel.test.TestStatic ");
System.out.println( "加载com.daniel.test.TestStatic成功! ");
System.out.println( "准备实例化com.daniel.test.TestStatic... ");
TestStatic ts = (TestStatic)clazz.newInstance();
System.out.println( "实例化com.daniel.test.TestStatic成功! ");
ts.print();
}
}
只要你看一下运行结果就可以证明你的以下观点:
=====================================
静态块里的代码不一定是第一次被加载时执行,
确切的说应该是第一次实例化的时候执行~
===================================
是错误的
[解决办法]
=============================================================================
支持楼主!
帮楼主找到了一个理论依据:在 Java Language Specification 中找到这样一句“Any static initializers declared in a class are executed when the class is initialized”,也就是说,并不是在“加载(loadClass)”的时候,而是在“initialized”的时候。
至于什么时候是“initialized”,也不难找到,用如下代码就能清楚地看到了:
=============================================================================
楼主说的是“实例化”,而不是initialized,
“实例化”与class is initialized是两回事。
[解决办法]
强烈建议楼主把 < <深入JAVA虚拟机> > 买回来,好好看看“第7章 类型的生命周期”,
然后再来好好总结一下。
[解决办法]
> 楼主说的是“实例化”,而不是initialized,
> “实例化”与class is initialized是两回事。
不错,我发帖子说“支持楼主”的时候,只是通过 (new Throwable()).printStackTrace() 的方式看到执行静态初始化代码的时候确实是在 newInstance() 的过程中,当时我也没分清“实例化”和“initialized”。现在看起来,“类加载”、“类初始化”和“实例化”是三个不同的过程,其中“类初始化”从表现上一般跟“实例化”是一起的,但也有可能是分离的。
不可否认,楼主提出了一个我们往往忽略的细节。对这个细节的掌握虽然无助于日常的 coding 工作,但适当地思考一下此类问题,对于深入理解一门语言是有帮助的。我喜欢这样的问题,感谢楼主 :)