当我基于我的c++知识使用Java时,我喜欢使用以下方式初始化变量。

public class ME {
    private int i;

    public ME() {
         this.i = 100;
    }
}

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

public class ME {
    private int i = 100;

    public ME() {
    }
}

我遇到了其他人的源代码,一些使用第1公约,其他人使用第2公约。

请问你们都推荐哪个会议?为什么?


当前回答

如果你在顶部或构造函数中初始化,没有太大区别,但在某些情况下,在构造函数中初始化是有意义的。

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;
    }
}

根据不同的情况有时你需要在顶部初始化有时在构造函数中初始化。

供参考,不使用构造函数初始化的其他选项:

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;
    }    
} 

其他回答

我发现第二种风格(一次性声明+初始化)更好。原因:

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

当然,如果初始化值在不同的构造函数中是不同的(甚至在构造函数中计算),则必须在构造函数中进行。

如果你在顶部或构造函数中初始化,没有太大区别,但在某些情况下,在构造函数中初始化是有意义的。

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;
    }
}

根据不同的情况有时你需要在顶部初始化有时在构造函数中初始化。

供参考,不使用构造函数初始化的其他选项:

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;
    }    
} 

我认为两者都是正确的编程方式,

但是我认为你的第一个选择在面向对象的方式中更正确,因为在构造函数中是对象创建的时候,也是变量应该初始化的时候。

我认为这是“照章办事”的惯例,但它是可以讨论的。

维基百科

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

例如,在第二个代码片段中,可以删除构造函数,从而获得更清晰的代码。

我会说,这取决于默认值。例如

public Bar
{
  ArrayList<Foo> foos;
}

我将在构造函数之外创建一个新的数组列表,如果我总是假设foo不能为空的话。如果Bar是一个有效的对象,不关心foos是否为空,我将把它放在构造函数中。

您可能不同意,并说将对象置于有效状态是构造函数的工作。然而,如果显然所有的构造函数都应该做完全相同的事情(初始化foo),为什么要重复该代码呢?