Java实例变量用方法初始化

问题描述 投票:15回答:6

我对以下代码有点困惑:

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 compilation initialization instance-variables
6个回答
21
投票

int的默认值是0(参见here)。因为你在x之前初始化h,所以giveH将返回int的默认值(例如0)。

如果你这样切换订单

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

输出将是

29 29

4
投票

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

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

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

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

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


3
投票

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

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

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


2
投票

在字段初始化程序中使用方法是不好的做法。你可以通过制作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);          
    }
}

1
投票

如果我们不在此程序中初始化非静态变量(如x)的值,则JVM将为类级非静态变量提供默认值零。


0
投票

声明后,所有数组元素都存储其默认值。存储对象的数组中的元素默认为null。存储基本数据类型的数组元素存储:0表示整数类型(byte,short,int,long); 0.0表示十进制类型(float和double);布尔值为false; \ u0000用于char数据。

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

© www.soinside.com 2019 - 2024. All rights reserved.