我最近一直在用c#和Java编程,我很好奇初始化我的类字段的最佳位置在哪里。

我应该在申报时申报吗?:

public class Dice
{
    private int topFace = 1;
    private Random myRand = new Random();

    public void Roll()
    {
       // ......
    }
}

或者在构造函数中?:

public class Dice
{
    private int topFace;
    private Random myRand;

    public Dice()
    {
        topFace = 1;
        myRand = new Random();
    }

    public void Roll()
    {
        // .....
    }
}

我很好奇你们这些老兵认为最好的做法是什么。我想保持一致,坚持一种方法。


当前回答

有许多不同的情况。

我只需要一个空列表

情况很清楚。我只需要准备我的列表,并防止在有人向列表添加项时抛出异常。

public class CsvFile
{
    private List<CsvRow> lines = new List<CsvRow>();

    public CsvFile()
    {
    }
}

我知道价值观

我确切地知道在默认情况下我想要什么值,或者我需要使用一些其他逻辑。

public class AdminTeam
{
    private List<string> usernames;

    public AdminTeam()
    {
         usernames = new List<string>() {"usernameA", "usernameB"};
    }
}

or

public class AdminTeam
{
    private List<string> usernames;

    public AdminTeam()
    {
         usernames = GetDefaultUsers(2);
    }
}

可能值的空列表

有时我希望默认情况下是一个空列表,并可以通过另一个构造函数添加值。

public class AdminTeam
{
    private List<string> usernames = new List<string>();

    public AdminTeam()
    {
    }

    public AdminTeam(List<string> admins)
    {
         admins.ForEach(x => usernames.Add(x));
    }
}

其他回答

如果我告诉你,这要看情况?

我通常初始化所有东西,并以一致的方式进行。是的,它过于明确,但它也更容易维护。

如果我们担心性能,那么我只初始化必须要做的事情,并将其放在性价比最高的地方。

在实时系统中,我甚至怀疑我是否需要变量或常数。

在c++中,我经常在这两个地方都不初始化,而是将它移动到Init()函数中。为什么?好吧,在c++中,如果你初始化的东西可能会在对象构造过程中抛出异常,你就会导致内存泄漏。

我通常尝试构造函数不做任何事情,只是获取依赖项并初始化相关的实例成员。如果您想对类进行单元测试,这将使您的工作更加轻松。

如果要分配给实例变量的值不受要传递给构造函数的任何参数的影响,则在声明时分配它。

保持一致很重要,但你要问自己这个问题: “我还有其他的构造函数吗?”

通常,我正在为数据传输创建模型,类本身除了作为变量的外壳外什么也不做。

在这些场景中,我通常没有任何方法或构造函数。对我来说,只为了初始化列表而创建构造函数会感觉很愚蠢,特别是因为我可以在声明中对它们进行内联初始化。

正如许多人所说,这取决于你的使用习惯。保持简单,不要做任何不必要的额外事情。

当你不需要一些逻辑或错误处理时:

在声明时初始化类字段

当你需要一些逻辑或错误处理时:

在构造函数中初始化类字段

当初始化值可用时,这工作得很好 初始化可以放在一行上。然而,这种形式 初始化因为简单而有局限性。如果 初始化需要一些逻辑(例如,错误处理或 对于循环填充复杂数组),简单的赋值是不够的。 实例变量可以在构造函数中初始化,其中error 可以使用处理或其他逻辑。

来自https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html。

我的规则:

不要初始化声明中的默认值(null, false, 0, 0.0…) 如果没有改变字段值的构造函数形参,最好在声明中初始化。 如果字段的值因构造函数形参而改变,则将初始化放在构造函数中。 坚持练习(这是最重要的规则)。