【问题标题】:Which constructor is called in the following code以下代码中调用了哪个构造函数
【发布时间】:2016-09-11 17:07:23
【问题描述】:

我对空构造函数的目的感到困惑,让我详细说明一下:

如果我有课..

public class Test {
  private int x;
  private int a[];
  private static int y;

  public Test() {
     a = new int[3];
  }
}

我知道存在一个空的默认构造函数:

public Test() {
                      //or at least I think it exists
}                     //what is its purpose?

如果我有一个 main 方法并编写以下代码:

Test t1 = new Test();

调用了哪个构造函数?还是空的构造函数被实例化 a[] 的构造函数覆盖?

如果我随后实例化 5 个 Test 实例,分配多少整数内存位置?

好糊涂……

【问题讨论】:

  • 这看起来像你在做作业。我会阅读帖子的规则问题。还要确保您自己进行研究和搜索网络,以避免这样的反应。
  • 你是对的,默认情况下会有一个默认构造函数,即没有参数的构造函数。如果您编写自己的构造函数也不带参数,那么这将覆盖默认构造函数。
  • 空的构造函数只有在你没有明确定义时才存在。
  • 澄清:默认构造函数由编译器创建,如果您没有任何构造函数。任何构造函数,即使是带参数的构造函数,都会抑制默认构造函数。
  • 感谢@Scary Wombat、shmosel 和 Andreas 为我澄清了这一点。我没有意识到默认值被无参数方法抑制。谢谢戴尔。

标签: java memory constructor


【解决方案1】:

空构造函数继承自Object类,它是Java中所有类的超类。它只是分配对象的内存,但不初始化任何东西。 所以对于每个对象都可以调用new A(),即使public A() 没有明确定义。 有时你不需要在构造函数中做额外的工作,所以你可以使用默认的而不需要重新实现它。

当一个子类覆盖它时,被调用的就是新的。这很有意义,因为当您费心重写一个方法时,您希望能够使用它而不是默认方法。

在您的示例中,Test 类包含 2 个整数和一个由 3 个整数组成的数组。 每次实例化一个新的Test 时,都会为另外两个整数和三个整数的数组分配空间。这就是为什么这些被称为 instance 变量的原因:这意味着它们属于一个实例。所以每个实例都有自己的。

【讨论】:

  • Claverine 所以你的意思是,即使我调用构造函数并且它初始化了三个数组(变量 a),系统仍然为另外两个 int x 和 static int y 分配内存?
  • 对不起,我忽略了静态整数。静态属性是类变量,即所有实例都相同。所以在调用构造函数时,会为x和a分配空间。 y 的空间只在类中分配一次,无论您创建多少实例。所以是的,当您实例化 5 个实例时,系统为每个实例分配 4 个整数(用于 x 和 a)加上 1 个整数用于 y(由所有实例共享)。总共有 21 个整数。
  • 谢谢! @T.Claverine 即使构造函数没有提及 int x 也是如此(仅初始化了'a')......每个实例的 x 值中保存的是什么;是空的吗?
【解决方案2】:

如果你没有为你的类定义任何构造函数,那么编译器会自动为你的类定义添加一个默认的无参数构造函数,以便可以使用 new 关键字创建对象。如果您自己显式定义无参数构造函数(您所做的方式),那么编译器将不会从他身边添加任何东西。

所以在这行代码中

Test t1 = new Test();

将调用您明确定义的构造函数。

回答您的第二个问题 - 您的类的每次实例化都会分配保存包含 3 个整数的数组所需的内存。对于 5 个实例,它将简单地变为 5 次。

5 * 3 * memory occupied by one integer

【讨论】:

    【解决方案3】:

    调用了哪个构造函数?还是空的构造函数被实例化 a[] 的构造函数覆盖?

    由于你已经为 Test 类提供了构造函数,你的构造函数将被调用。 如果您想显式调用超类构造函数,请将代码更改为

     public Test() {
         super();
          a = new int[3];
     }
    

    来自constructors上的 oracle 文档页面

    您不必为您的类提供任何构造函数,但这样做时必须小心。编译器会自动为任何没有构造函数的类提供无参数的默认构造函数。此默认构造函数将调用超类的无参数构造函数。在这种情况下,如果超类没有无参数构造函数,编译器会报错,因此您必须验证它是否存在。如果你的类没有显式超类,那么它有一个 Object 的隐式超类,它确实有一个无参数构造函数


    如果我随后实例化 5 个 Test 实例,分配多少整数内存位置?

    1. JVM将为静态变量(int y,即类或静态变量)分配1个整数的空间

    2. JVM将为int x的每个Test实例分配1个整数空间,即实例变量

    3. JVM会为int a[]数组的每个Test实例分配3个整数的空间,这个数组是实例变量

    总计:5 + 5 + 15 (=25) 个整数的空间

    【讨论】:

      猜你喜欢
      • 2021-09-01
      • 1970-01-01
      • 2013-05-14
      • 1970-01-01
      • 2017-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多