论坛首页 入门技术论坛

类的装载、连接与初始化 -- 纠正

浏览 7511 次
该帖已经被评为新手帖
作者 正文
   发表时间:2010-07-02  
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) Client VM (build 14.3-b01, mixed mode, sharing)
0 请登录后投票
   发表时间:2010-07-02   最后修改:2010-07-02
maozj 写道
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) Client VM (build 14.3-b01, mixed mode, sharing)

我比较感兴趣的是,为什么在上面的版本会出现问题? 期待楼主解答……
0 请登录后投票
   发表时间:2010-07-02  
可能楼主把NewbornBaby中的hoursOfCrying敲成了hoursOfSleep
0 请登录后投票
   发表时间:2010-07-02  
guzhan 写道
可能楼主把NewbornBaby中的hoursOfCrying敲成了hoursOfSleep

人家就是hoursOfSleep好吧……文章中也是哇
0 请登录后投票
   发表时间:2010-07-02  
真是奇怪了,竟然有人是,有人不是,看来谁的代码肯定有问题。
0 请登录后投票
   发表时间:2010-07-03   最后修改:2010-07-03
楼上的各位大大们在讨论的时候为何没有人把自己测试的代码以文本形式贴出来保证大家用同样的代码测试呢?
原始代码在官网可以找到,http://www.artima.com/insidejvm/ed2/lifetype4.html
// On CD-ROM in file classlife/ex2/NewParent.java
class NewParent {

    static int hoursOfSleep = (int) (Math.random() * 3.0);

    static {
        System.out.println("NewParent was initialized.");
    }
}

// On CD-ROM in file classlife/ex2/NewbornBaby.java
class NewbornBaby extends NewParent {

    static int hoursOfCrying = 6 + (int) (Math.random() * 2.0);

    static {
        System.out.println("NewbornBaby was initialized.");
    }
}

// On CD-ROM in file classlife/ex2/Example2.java
class Example2 {

    // Invoking main() is an active use of Example2
    public static void main(String[] args) {

        // Using hoursOfSleep is an active use of NewParent,
        // but a passive use of NewbornBaby
        int hours = NewbornBaby.hoursOfSleep;
        System.out.println(hours);
    }

    static {
        System.out.println("Example2 was initialized.");
    }
}


Example2的Java代码本身是个陷阱。代码里虽然写的是NewbornBaby.hoursOfSleep,但因为hoursOfSleep不是NewbornBaby而是NewParent的静态变量,程序实际访问也是通过NewParent访问的
public static void main(java.lang.String[]);
  Code:
   Stack=2, Locals=2, Args_size=1
   0:   getstatic       #11; //Field NewParent.hoursOfSleep:I
   3:   istore_1
   4:   getstatic       #8; //Field java/lang/System.out:Ljava/io/PrintStream;
   7:   iload_1
   8:   invokevirtual   #9; //Method java/io/PrintStream.println:(I)V
   11:  return


各位大大贴运行结果请贴上使用的源码和编译后main方法的字节码来比对。
0 请登录后投票
   发表时间:2010-07-03  
小弟运行出来的结果和案列之中出来的结果一样的,并不是楼主所说的结果,不知楼主是不是创建了子类的对象才会产生这样的结果,并且小弟使用的版本为
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)
0 请登录后投票
   发表时间:2010-07-03  
ckn126 写道
小弟运行出来的结果和案列之中出来的结果一样的,并不是楼主所说的结果,不知楼主是不是创建了子类的对象才会产生这样的结果,并且小弟使用的版本为
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)

刚刚纠正了下 谢谢
0 请登录后投票
   发表时间:2010-07-03  
恩,俺的代码有问题……sh*t!哈哈,楼主修正后是正确滴~
0 请登录后投票
   发表时间:2010-07-03  
maozj 写道
首先纠正<<深入java虚拟机>>电子书中的一个小错误(针对父类和子类拥有共同static变量时),那么父类和子类static变量,static块都会初始化。

楼主大大修改后主楼的描述还是容易误导咱小的呀。修改后第二版本代码,也就是
class NewParent {     
     
    static int hoursOfSleep = (int) (Math.random() * 3.0);     
     
    static {     
        System.out.println("NewParent was initialized.");     
    }     
}     
  
class NewbornBaby extends NewParent {     
     
    static int hoursOfSleep = 6 + (int) (Math.random() * 2.0);     
     
    static {     
        System.out.println("NewbornBaby was initialized.");     
    }     
}     
  
class Example2 {     
    public static void main(String[] args) {     
        int hours = NewbornBaby.hoursOfSleep;
        System.out.println(hours);     
    }     
     
    static {     
        System.out.println("Example2 was initialized.");     
    }     
}

NewParent.hoursOfSleep与NewbornBaby.hoursOfSleep只是同名,却是两个完全独立的变量,本质上说跟一个叫abc另一个叫def一样。
父子类里同名变量会引发名字遮盖现象,通过"NewbornBaby.hoursOfSleep"只能访问到NewbornBaby.hoursOfSleep而无法访问到NewParent.hoursOfSleep。名字规则由Java语言规范第三版第六章定义。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics