我也感觉两者一样,但是我在代码1给number加个引用就可以执行了!所以我推断java系统弄不清改给谁使用!

解决方案 »

  1.   

    public class Mytest2 {
    private final int number;

    {
    printProperty();
    number = 3;
    printProperty();
    }

    private static void printProperty(){
        System.out.println(number);
    }

    public static void main(String[] args) {
    Mytest2 test = new Mytest2();
    }
    }
    non-static variable number cannot be referenced from a static context
                System.out.println(number);
                                   ^
    1 error
    说明一个问题,JAVA程序里任何一个非静态函数的调用都是在赋值过程之后,也就是说即使在块中,它也会先赋值再调用函数,所以顺序上始终是赋值在前,无论你写出来是什么顺序。但是有静态函数就除外,我把你的函数改成静态的,那么它会突破上面的限制,先调用静态函数,那么将会先进行打印,但是此时number还没有值,故报错。但是如果你不是申明为final的,即使是上面那样修改成静态的也不会报错,因为那样的话会赋值为默认值0。
      

  2.   

    构建对象时---即进入构造函数:
       1,先由系统初始化实例字段为0,false和null---如为类的首次加载,静态字段也初始化。
            这是为了安全而由系统执行的,与final无关。
       2,按顺序执行所有字段初始化语句和初始化块。
       3,构造器主体。    System.out.println(number); 此时,number已经是0,但编译器发现你没有显式初始化而使用,所以抱错。
        printProperty();  则编译器执行函数,  编译器由于number已经是0,可以顺利执行。  而编译器没有发现你使用了没有显式初始化的字段。
          编译器 报错的目的是:  提醒你可能的失误,它也有检测不到你编程不规范的情况。    你的程序编写时不规范的!   但是可以执行!
      

  3.   

    star_str(生命火花) 
    我也感觉两者一样,但是我在代码1给number加个引用就可以执行了!所以我推断java系统弄不清改给谁使用!
        --------------------------------------------------------------------------------
       你怎么给number加个引用,  number 又不是对象!
      

  4.   

    to shendl(良少) 
    ================================
    你的意思是,代码1和代码2之所以不同,是因为compiler的原因造成的 ?
      

  5.   

    对于你的疑问:
    1. 代码1和代码2我认为是一样的,为什么2能运行,1不能运行?
    2. 为什么常量number在被赋了默认值后,我还能对它进行赋值?1:“1”不是不能运行而是编译时就报错了(当然谈不上运行),因为编译器检查到了这个错误:The black final field may not be initialized.
    1:2: "2"结构上没错,编译器通过了。在执行时构造number对象时分配了内存空间,执行器暂赋值0给numer,但不是final值,jvm允许运行期赋final变量的值(但不允许多次赋值),所以number = 3;有效。