我<<深入jvm>>中有这么一个定义
An active use of a class is: * The invocation of a constructor on a new instance of the class
* The creation of an array that has the class as its an element type
..................我对它的第二点很坏疑,理由:
/*
*以下程序不能输出任何东西
(一般情况下我一定会认为是作者写错了^ ^,但是考虑到作者应该是参考了 jvm specification,那个东西就不太能够怀疑了,呵呵,所以我很相信是自己理解错了)
*/
class A {
static {
System.out.println("A is initialized");
}
}public class Test {
public static void main(String[] args){
A[] as = new A[0]; //我觉得按作者说,应该是在执行这句时会初始化A类,但其实没有
}}
An active use of a class is: * The invocation of a constructor on a new instance of the class
* The creation of an array that has the class as its an element type
..................我对它的第二点很坏疑,理由:
/*
*以下程序不能输出任何东西
(一般情况下我一定会认为是作者写错了^ ^,但是考虑到作者应该是参考了 jvm specification,那个东西就不太能够怀疑了,呵呵,所以我很相信是自己理解错了)
*/
class A {
static {
System.out.println("A is initialized");
}
}public class Test {
public static void main(String[] args){
A[] as = new A[0]; //我觉得按作者说,应该是在执行这句时会初始化A类,但其实没有
}}
应该可以输出东西啊
不是有个静态语句块吗,有输出的啊
不然只是声明的话,jvm会检查这个类有没有可能用到,如果没可能用到,类是不会被加载进来的,只有当有可能用到的时候才能被加载
A a1;
a1.m1();
这样根本不会返回nullpointexception,而是把你的static代码块的东西输出来了,为什么呢,因为static方法是已经准备好的,不需要初始化的
为什么声明时候不会输出代码块的东西?就是因为,我们还不需要用到这个类,jvm认为,在不需要用到的时候把类加载进来,这是很浪费资源的。
测试了一下:
public static void main(String[] args) {
A[] as = new A[3]; //我觉得按作者说,应该是在执行这句时会初始化A类,但其实没有
System.out.println(as);
A a = new A();
}
使用netbeans调试跟踪,可以察看类加载器加载了哪些类,只有运行到A a = new A(); 的时候加载器里才出现了A这个类.也就是说创建数组的时候没有加载.
应该是作者说的第一点:“The invocation of a constructor on a new instance of the class ”呵呵
我基本上赞成这个观点,但我加一点“java编译器是会做手脚的”呵呵,也就是同
Integer objectI = 2; //一个道理,其实并非把直接量赋给对象合理,而是java编译器把“2”在包装了一下a1.m1();其实也一样,其实编译时编译器把a1“很明显地”改为了A,(也就是编译器把a1看作了A)
而不是说通过对象访问static方法本来就是一件合理的事,(所以好多书上都会这么讲,尽量不要用对象去访问类方法,理由就在这里)
尽管“因为static方法是已经准备好的”在运行时应该是一定不可以的理由如下:class A {
static void doit(){
}
}public class Test {
public static void main(String[] args){
A a1 = null;
a1.doit();
}
}反编译:public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: returnpublic static void main(java.lang.String[]);
Code:
0: aconst_null
1: astore_1
2: aload_1
3: pop
4: invokestatic #2; //Method A.doit:()V ******************请看这里invokestatic而不是invokevirtual
7: return}