【问题标题】:Initialization of class variables in constructor in javajava中构造函数中类变量的初始化
【发布时间】:2014-10-23 10:18:14
【问题描述】:

我们知道……

实例变量在默认构造函数中初始化。例如。

public class H{
    int x;

    public static void main(String... args){
        System.out.print(new H().x);
    }
}

上面代码的O/P是0,因为有一个默认的构造函数被调用,并且该构造函数将x初始化为0。

现在,我的问题是,如果我们运行下面的代码,即

public class H{
        int x;

        public H(){}

        public static void main(String... args){
            System.out.print(new H().x);
        }
}

在这种情况下实际的O/P也是0,但我认为应该有编译器错误x没有初始化,因为我们已经覆盖了默认构造函数并且没有初始化x我认为我已经把我的问题说清楚了..

【问题讨论】:

  • 实例变量根据其类型初始化为默认值。
  • 但是初始化是在默认构造函数中完成的,我的问题是在第二个代码中,对默认构造函数的调用永远不会发生..
  • 字段初始化发生在构造函数调用之前。

标签: java constructor instance-variables


【解决方案1】:

实例变量具有与之关联的默认值

来自The Java™ Tutorials

默认值

声明字段时并不总是需要赋值。已声明但未初始化的字段将由编译器设置为合理的默认值。一般而言,此默认值将为零或空,具体取决于数据类型。

【讨论】:

  • 它们真的被编译器初始化了吗?它们不是在运行时由 jvm 简单地初始化吗?因为如果你是对的,我应该在编译器生成的字节码中看到显式的字段初始化,我怀疑是这种情况。
  • 这个document 说它们是由编译器初始化的
  • 有趣。看起来你是完全正确的。它们可能存储在类文件的初始化表中,而不是直接存储在字节码中。我会想不同的。为课程 +1。
  • @EdwinDalorzo:我认为该文档的术语有点松散。正如您所说,初始化实例成员的字节码中没有任何内容,而且它的 种类 似乎更像是 JVM 的责任而不是编译器的责任。并不是说它真的很重要......
  • @TJCrowder 我需要再次阅读 JVM 规范,但我认为可能发生的情况是编译器在某种初始化表中设置了初始化值,然后 JVM 读取这些值并初始化田野。因此,最终它必须是在运行时完成工作的 JVM,这是肯定的。通过反编译源代码,它不会发生显式字节码,这就是为什么我认为它们可能是由编译器在二进制类文件的某种表中编写的。
【解决方案2】:

在 Java 中,实例成员默认为其值的全位关闭版本(ints 是 0,对象引用是 nullfloats0.0,布尔值是 @ 987654326@,等等)。这不是默认构造函数执行的操作,它在构造函数运行之前完成

顺序是:

  1. 将实例成员默认为其全位关闭值。 (如果优化器看到下面的 #2 或 可能 如果它可以向自己证明在下面的 #3 初始化之前没有使用该成员,则优化器可以跳过此操作。)

  2. 应用它们的任何内联初始化。例如:

    int a = 42;
    
  3. 按源代码顺序应用实例初始化块。

  4. 调用适当的构造函数。

例如:

class Example {

    int a = 42;

    // Instance initializer block:
    {
        this.a = 67;
    }

    Example() {
        System.out.println(this.a);
    }
}

new Example() 输出67

显然,在这两个地方进行初始化是不好的做法,这只是为了说明。

【讨论】:

    【解决方案3】:

    Java 对程序员来说非常简洁(不像其他语言,例如 C),这意味着它会自动初始化字段。一个例外是 final 字段和方法内的字段(编译器将在其中产生错误)。

    希望对您有所帮助。

    【讨论】:

    • “方法中的字段”是什么意思?你知道已经有其他几个答案了。您应该更详细地阐述您的想法,并为答案提供示例和不同的观点,尤其是如果您想要更多的赞成票。如果您详细说明,我会考虑为您投票。
    • 非常感谢您的反馈。由于已经给出了一个非常好的和图解的答案,我不会编辑我的,但我不接受我可以给出的未来答案!
    【解决方案4】:

    无论构造函数是否已重载(或添加了显式无参数构造函数),所有实例级变量都将初始化为其默认值。构造函数只是更改默认值。

    【讨论】:

      【解决方案5】:

      在java中默认初始化非final字段。默认情况下,只有方法和最终字段中的变量不会被初始化。

      如果您已将 x 声明为 final,那么您将是正确的。代码中会出现编译错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-09-27
        • 2015-02-19
        • 2017-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多