从根本上来讲的话class Test { int i=j; int j=10; } 应该是没有错误的,按照java中构造的顺序来讲,上面的代码应该是等同于: class Test { int i; int j; public Test() { i=j; j=10; }} 下面的这种形式在编译时并没有错误。而如果上面那种形式假设编译不出错的话,其实和下面的是一样的(编译后的结果),但是由于java编译器在设计的时候考虑到前一种形式的代码编写者的意图是想将i初始化为和j一样的值,即10,但是实际的结果是如果这样编译通过的话,初始化完成后i的值将是0而不是10,因此编译器禁止了这种前向引用以避免代码编写者的意图和程序实际编译的结果不同。而后一种情况可以由java规范解释,在进入构造方法前j实际上是已经初始化为0的,因此i此时可以进行引用,而且这个意图很明确,使用的就是j在内存分配后的初始值0。前一种情况不同,并不是太多的java程序员知道java编译器的工作过程,即:将成员变量声明时的赋值语句实际上放入构造方法中。 to Patrick_DK(疾风摩郎): 好好回顾一下我给你讲过的类构造的实际顺序。 看来我有必要再写一篇文章重申一下类构造的实际顺序。
to cherami(cherami):你讲过的类构造的实际顺序我其实已经比较清楚了,而且自己也组织过了. 我自己可能把实际运行和编译代码两种情况给分开了. 我再好好思考一下....
这种初始化方法非常简单和直观。它的一个限制是类型Measurement的每个对象都会获得相同的初始化值。有时,这正是我们希望的结果,但有时却需要盼望更大的灵活性
{
int i=j;
int j=10;
}
应该是没有错误的,按照java中构造的顺序来讲,上面的代码应该是等同于:
class Test
{
int i;
int j;
public Test() {
i=j;
j=10;
}}
下面的这种形式在编译时并没有错误。而如果上面那种形式假设编译不出错的话,其实和下面的是一样的(编译后的结果),但是由于java编译器在设计的时候考虑到前一种形式的代码编写者的意图是想将i初始化为和j一样的值,即10,但是实际的结果是如果这样编译通过的话,初始化完成后i的值将是0而不是10,因此编译器禁止了这种前向引用以避免代码编写者的意图和程序实际编译的结果不同。而后一种情况可以由java规范解释,在进入构造方法前j实际上是已经初始化为0的,因此i此时可以进行引用,而且这个意图很明确,使用的就是j在内存分配后的初始值0。前一种情况不同,并不是太多的java程序员知道java编译器的工作过程,即:将成员变量声明时的赋值语句实际上放入构造方法中。
to Patrick_DK(疾风摩郎):
好好回顾一下我给你讲过的类构造的实际顺序。
看来我有必要再写一篇文章重申一下类构造的实际顺序。
我自己可能把实际运行和编译代码两种情况给分开了.
我再好好思考一下....