public class Elvis {
        // Recursive class initialization
public static final Elvis ELVIS = new Elvis();

private Elvis() { 
    //System.out.println(ELVIS.LIVING);
}

private static final boolean LIVING = true; // Too late

private final boolean alive = LIVING;


public final boolean lives() { return alive; }

public static void main(String[] args) {
System.out.println(ELVIS.lives()? // Autounboxing!
"Hound Dog" : "Heartbreak Hotel");
}
为什么输出结果是Hound Dog?

解决方案 »

  1.   

    ELVIS.lives()的结果取决于 alive的值,而alive的值为LIVING = true,因此为true.
    ELVIS.lives()?  "Hound Dog" : "Heartbreak Hotel"
    这句就是如果ELVIS.lives()为真输出Hound Dog ,为假输出Heartbreak Hotel
      

  2.   

    按照我的理解,调用main,是对类Elvis的主动使用,导致类Elvis的初始化,给static字段进行赋值。
    执行:public static final Elvis ELVIS = new Elvis();
    构造new Elvis()对象
    执行:private final boolean alive = LIVING;
    此时的LIVING还没有初始化,保持其默认值false
    接着执行:private static final boolean LIVING = true;
    类初始化完毕
    main函数中调用ELVIS.lives()的时候,返回的应该是false,怎么会是true呢?jdb单步执行的结果:
    public static final Elvis ELVIS = new Elvis();private Elvis() {private final boolean alive = LIVING;}public static final Elvis ELVIS = new Elvis();System.out.println(ELVIS.lives()? // Autounboxing!public final boolean lives() { return alive; }System.out.println(ELVIS.lives()? // Autounboxing!
      

  3.   

    在构造new Elvis()对象 
    时就已经把alive赋为true了。
      

  4.   

    因为是final的,所以装载Elvis类时不会主动初始化ELVIS和LIVING,他们只是在使用的时候才会被初始化
    如果把final去掉就如同LZ在一楼所说的了
      

  5.   

    刚才又看了看深入java虚拟机的第七章,里面有一句话:
    如果类仅包含静态final变量的类变量初始化语句,并且这些类变量初始化语句采用编译时常量表达式,类就不会有<clinit>方法。
    例子中,private static final boolean LIVING = true; 这里的LIVING是常量,而非类变量
    用jad返编译生成的class可以看到:
    public final boolean lives()
    {
    return true;
    }
    代码中是直接嵌入的true的字面值。
      

  6.   

    ELVIS并不是常量,因此会初始化ELVIS
      

  7.   

    zhuzhusany说的是错的,我试过了
    goldenfish1919说的有道理
      

  8.   

    请lz分清编译器和解释器,当编译源文件时编译器已经给static final的赋值了,也就是编译之后你的LIVING=ture了