Java 实例变量初始化方法

Java instance variables initialization with method

我对下面这段代码有点困惑:

public class Test{

  int x = giveH();
  int h = 29;

  public int giveH(){
     return h;
  }

  public static void main(String args[])
  {
      Test t = new Test();
      System.out.print(t.x + " ");
      System.out.print(t.h);          
  }
}

这里的输出是0 29,但是我想这一定是编译错误,因为在方法giveH()的时候变量h应该还没有初始化。那么,编译是从上到下逐行进行的吗?为什么这是有效的?为什么 x 的值是 0 而不是 29?

Java 中的编译不需要在使用前声明方法。 Java tutorial 更详细地介绍了初始化。

这里有一个思考的方法:编译器会记下在范围内某处寻找名为 giveH 的方法,只有当它离开范围并且找不到它时才会出错。一旦到达 giveH 声明,便条便已解决,大家都很高兴。

此外,Java中实例变量的变量初始化被移动到构造函数的开头。你可以认为上面的行被分成两部分,上面的 x 和 h 的声明,以及构造函数中的赋值。

声明的顺序在这种情况下很重要。当变量 x 被初始化时,h 的 default value 为 0,因此 giveH() 将 return 该默认值。之后,变量h被赋值为29.

您还可以查看 Field Initialization and Forward References During Field Initialization 上的 Java 语言规范部分。

int 的默认值为 0(参见 here)。因为您在 h 之前初始化 xgiveH 将 return 为 int 的默认值(例如 0)。

如果你这样调换顺序

int h = 29;
int x = giveH();

输出将是

29 29

@Maloubobola 给出了正确的答案,但由于您似乎还没有完全理解,所以让我尝试详细说明。

创建Test时,它会运行一次变量初始化(x = giveH(), h= 29)。你的误解可能是变量 x 总是由 giveH() 决定的,而它只在 x 初始化时决定它的值。

这就是为什么语句的顺序在这里很重要; x 在 h 之前初始化,因此在 x 初始化时调用 giveH() 时 h 为 0。

如果我们不在这个程序中初始化像 x 这样的非静态变量的值,JVM 将为 class 级别的非静态变量提供默认值零。

在字段初始值设定项中使用方法是不好的做法。您可以通过将 h 设置为 final 来解决此问题。然后它将在加载 class 时初始化。

import java.util.ArrayList;

public class Test {
    int x = giveH();
    final int h=29;

    final public int giveH(){
        return h;
    }

    public static void main(String args[]) {
        Test t = new Test();
        System.out.print(t.x + " ");
        System.out.print(t.h);          
    }
}

一旦声明,所有数组元素都会存储它们的默认值。 存储对象的数组中的元素默认为空。 存储原始数据类型的数组元素存储: 0 表示整数类型(byte、short、int、long); 0.0 用于十进制类型(浮点型和双精度型); 布尔值是假的; \u0000 用于字符数据。

Actauls 值只有在我们给它们初始化时才会出现