【问题标题】:Java instance variables initialization with method使用方法初始化 Java 实例变量
【发布时间】:2016-02-13 15:14:57
【问题描述】:

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

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?

【问题讨论】:

  • 这是因为做事的顺序。 1/ 事物声明 2/ 定义(如果需要)。像这样考虑:int h; int x; x = giveH(); h = 29;

标签: java compilation initialization instance-variables


【解决方案1】:

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

这是一种思考方式:编译器会记下在范围内的某处寻找名为 giveH 的方法,并且只有在离开范围但找不到它时才会出错。一旦它到达 giveH 声明,那么便条就解决了,每个人都很高兴。

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

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

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

【讨论】:

  • 好的,谢谢..但是当排序无关紧要时,为什么 x 的值是 0 而不是 29?导致方法 giveH()“知道”有一个名为“h”的实例变量,因为该方法返回它的值..所以我不明白为什么它返回 0。
  • 好的,我认为这实际上是一个不正确的说法。排序确实很重要。我将进行编辑以明确这一点。
【解决方案2】:

int 的默认值为0(请参阅here)。因为您在h 之前初始化x,所以giveH 将返回一个int 的默认值(例如0)。

如果你像这样切换顺序

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

输出将是

29 29

【讨论】:

  • 是的,但是 giveH() 返回 h 的值,所以这些方法知道“h”......并且 h 被初始化为 29..所以我不确定我明白了.
  • 该方法知道 h,但不知道他的值。当你调用giveH() 时,h 没有初始化,所以他的值是0(不是 29,顺序很重要)。 giveH() 在初始化变量时只调用一次。
  • 应该区分变量声明,即“我的变量hint”这一事实,以及变量定义,即“我的整数@987654335”这一事实@ 的值为 29"。当您的变量x 被初始化时,它会调用方法giveH(),该方法检索h 的值。此时,由于h的初始化是在x之后进行的,所以只声明了变量h(否则代码无法编译)。默认情况下,int 变量的值被赋予0,直到它的值被声明。这就是为什么你从giveH() 得到0,而不是29 也不是编译错误
  • 我没想到,非常好,+1。我以前也从未遇到过 - 将实例变量设置为实例方法的结果有点不寻常。
  • 可能应该注意,发生这种情况的原因是因为初始化 x 只发生了一次。所以 x 的值等于 h 类初始化时的值。新开发人员的一个常见误解是认为将变量设置为方法的结果会使变量的值等于执行中任何给定点的方法的结果。这是错误的。
【解决方案3】:

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

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

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

      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);          
          }
      }
      

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-10-06
          • 2014-09-14
          • 2013-08-14
          • 1970-01-01
          • 2011-09-24
          • 2010-12-01
          • 2017-10-23
          相关资源
          最近更新 更多