Java 什么';在字段中实例化和在构造函数中实例化有什么区别?

Java 什么';在字段中实例化和在构造函数中实例化有什么区别?,java,Java,这样做的区别是什么: public class SomeClass { SomeObject obj = new SomeObject(); //rest of the code } 还有这个 public class SomeClass { SomeObject obj; public SomeClass(){ obj = new SomeObject(); } //rest of the code } 施工时间。第一个是在输入

这样做的区别是什么:

public class SomeClass {
    SomeObject obj = new SomeObject();
    //rest of the code
}
还有这个

public class SomeClass {
    SomeObject obj;
    public SomeClass(){
       obj = new SomeObject();
    }
    //rest of the code
}

施工时间。第一个是在输入main之前完成的。另一个对象的构造被延迟,直到调用某个类的ctor为止。

在第一个实例中,
obj
将在构造函数运行之前初始化。当您有子类时,这是一个重要的细微差别。构造函数和初始化块的顺序为:

  • 超类初始值设定项
  • 超类构造函数
  • 子类初始值设定项
  • 子类构造函数

  • 唯一的区别是在引用被初始化时。最终效果相同。

    根据Java语言规范的章节:

    就在提到新的 创建的对象将作为 结果,指示的构造函数为 已处理以初始化新对象 使用以下程序:

  • 将构造函数的参数分配给新创建的参数 此构造函数的变量 调用
  • 如果此构造函数以显式构造函数调用 同一类中的另一个构造函数 (使用此选项),然后评估 参数并处理该构造函数 使用这些函数递归调用 同样的五个步骤。如果这个构造器 调用突然完成,然后 此过程突然完成,原因如下: 同样的原因;否则,请继续 第五步
  • 此构造函数不以显式构造函数开头 在中调用另一个构造函数 相同的类(使用此)。如果这 构造函数适用于除 对象,则此构造函数将 从显式或隐式开始 调用超类构造函数 (使用super)。评估论点 并处理这个超类 构造函数递归调用 使用同样的五个步骤。如果 构造函数调用完成 突然,那么这个程序 为了同样的目的突然完成 原因。否则,继续执行步骤
  • 执行的实例初始值设定项和实例变量初始值设定项 此类,指定 实例变量初始值设定项到 对应的实例变量,在 从左到右的顺序 以文本形式出现在源代码中 为了班级。如果执行任何 这些初始值设定项会导致 例外,那么就没有其他了 初始值设定项已处理,并且 这个过程就这样突然结束了 同样的例外。否则,请继续 第五步。(在一些早期 实现,编译器 错误地忽略了要删除的代码 如果字段不可用,则初始化字段 初始化表达式是一个常量 值等于的表达式 的默认初始化值 它的类型。)
  • 执行此构造函数主体的其余部分。如果那次处决 突然完成,然后这个 该过程突然完成 同样的原因。否则,请执行此步骤 正常完成

  • 因此,不同之处在于步骤(步骤4或步骤5),但结果是相同的。

    这只是风格问题,它编译为相同的代码


    就我个人而言,我倾向于将实例的所有初始化放在构造函数中,因为这对所有情况都是一致的。

    一个方面尚未提及:

    public class SomeClass {
        SomeObject obj = new SomeObject();
        //rest of the code
    }
    
    将obj初始化为固定值。但是在构造函数中初始化时,可以让初始化依赖于构造函数的参数,或者(对于多个构造函数)使用完全不同的初始化表达式,例如

    public class SomeClass {
        private SomeObject obj;
        public SomeClass(int length){
           obj = new SomeObject(3 * length + 7);
        }
        //rest of the code
    }
    

    这不是我对JLS第12.5条的解释,我认为这不是真的,这是错误的。javac在调用超级构造函数后在构造函数中生成代码。我理解C#是不同的(但你不能在这样的表达式中使用
    this
    )(第一个示例将在运行构造函数之前创建SomeObject…正确吗?答案就像从JLS复制的@Pascal一样,请参见#4和#5)。