我应该在构造函数或外部构造函数中初始化变量

Che*_*eng 215 java

当我根据我的C++知识使用Java时,我喜欢使用以下方式初始化变量.

public class ME {
    private int i;

    public ME() {
         this.i = 100;
    }
}
Run Code Online (Sandbox Code Playgroud)

过了一段时间,我改变了习惯

public class ME {
    private int i = 100;

    public ME() {
    }
}
Run Code Online (Sandbox Code Playgroud)

我遇到了其他的源代码,有些使用了第1个约定,有些则使用了第2个约定.

我可以知道你们都推荐哪种惯例,为什么?

sle*_*ske 203

我发现第二种风格(声明+初始化一次性)优越.原因:

  • 它一目了然地表明变量是如何初始化的.通常,在阅读程序并遇到变量时,您将首先转到其声明(通常在IDE中自动执行).使用样式2,您可以立即看到默认值.对于样式1,您还需要查看构造函数.
  • 如果您有多个构造函数,则不必重复初始化(并且您不能忘记它们).

当然,如果初始化值在不同的构造函数中不同(或者甚至在构造函数中计算),则必须在构造函数中执行此操作.

  • 为了解决第二个问题,我通常创建一个包含将重复的代码的私有构造函数,然后在所有其他构造函数的开头调用`this(privateConstructorArgs)`. (25认同)
  • 您还可以定义一个实例初始化程序,而不是从所有其他构造函数定义和调用私有构造函数,该初始化程序将在每个构造函数之前自动调用.这样,当您添加一些新的构造函数时,您将不必记住调用私有构造函数. (2认同)

Col*_*ert 23

我倾向于使用第二个来避免复杂的构造函数(或无用的构造函数),我也不认为这是初始化(即使它是初始化),但更像是给出一个默认值.

例如,在第二个代码段中,您可以删除构造函数并获得更清晰的代码.


小智 23

我有几乎总是在构造函数中初始化的习惯(习惯)有两个原因,一个在我看来它增加了readablitiy(更干净),两个在构造函数中比在一行中有更多的逻辑控制.即使最初实例变量不需要逻辑,但如果需要,在构造函数中使用它可以为将来添加逻辑提供更大的灵活性.

至于上面提到的关于多个构造函数的问题,通过使用一个no-arg构造函数来初始化所有构造函数初始化所有构造函数,然后每个构造函数在第一行调用this(),这很容易解决.这解决了你的reduncancy问题.


小智 6

我在第一种方法中看到的唯一问题是,如果您计划添加更多构造函数.然后你将重复代码,可维护性将受到影响.

  • 您始终可以链接构造函数. (17认同)
  • @Colin Hebert:它可以,但如果设计得好也可以优雅. (5认同)

Emi*_*mil 6

如果你在顶层或构造函数中初始化它没有太大的区别.但在某些情况下,在构造函数中初始化是有道理的.

class String
{
    char[] arr/*=char [20]*/; //Here initializing char[] over here will not make sense.
    String()
    {
        this.arr=new char[0];
    }
    String(char[] arr)
    {
        this.arr=arr;
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,根据具体情况,您必须在顶部初始化,有时在构造函数中初始化.

FYI其他选项用于初始化而不使用构造函数:

class Foo
{
    int i;
    static int k;

    //instance initializer block
    {
        //run's every time a new object is created
        i=20;
    }

    //static initializer block
    static{
        //run's only one time when the class is loaded
        k=18;
    }    
} 
Run Code Online (Sandbox Code Playgroud)


Ber*_*ard 5

我建议在构造函数中初始化变量。这就是它们存在的原因:确保正确构造(初始化)您的对象。

无论哪种方式都可以,并且这是样式问题,但是我更喜欢使用构造函数进行成员初始化。

  • 我真的不认为提供默认值是对象构造的一部分。但是正如您所说,这是风格问题。 (3认同)