设置和实例化类级变量的正确方法是什么?

时间:2012-01-14 02:29:34

标签: c# java instantiation

(在java或c#中)是否存在差异:

public class Foo {
  Bar1 bar1;
  Bar2 bar2;

  public Foo(Bar1 bar1, Bar2 bar2) {
    this.bar1 = bar1;
    this.bar2 = bar2;
  }
}

并且

public class Foo {
  Bar1 bar1 = null;
  Bar2 bar2 = null;

  public Foo(Bar1 bar1, Bar2 bar2) {
    this.bar1 = bar1;
    this.bar2 = bar2;
  }
}

对于对象,无论你是否指定null都无关紧要 - 它是隐含的,对吧?

我的老板坚持要分配每个值null。对于字符串,我理解分配String str = "",因为那里有很大的不同,但我不太确定为什么对象很重要。

此外,执行以下操作是不好的做法:

public class Foo {
  Bar1 bar1 = new Bar1();
  Bar2 bar2 = new Bar2(); 

  public Foo(Bar1 bar1, Bar2 bar2) {
    this.bar1 = bar1;
    this.bar2 = bar2;
  }
}

4 个答案:

答案 0 :(得分:4)

无需将实例变量显式初始化为默认值。在Java和C#中,在创建实例时为实例变量分配默认值。在构造函数运行的主体之前,引用类型已经 null。 int已经是0等。在第一个代码段中,bar1和bar2已经为空。没有需要来明确说明它,就像在第二个片段中一样。

在第二个示例(第三个代码段)中,如果你所做的只是用构造函数中的另一个引用覆盖,则绝对不需要将实例变量实例化为new Bar1();

当构造函数尚未使用提供的参数立即覆盖默认值时,您可能希望将成员变量初始化为值,而默认值应该是类型默认值以外的值。但将其设置为默认值只是多余的。但是,如果它可以帮助您的老板或团队的其他成员了解这些默认值是什么,那么就这样吧。

答案 1 :(得分:2)

如果您要在构造函数中指定一个类字段,通常没有充分的理由在字段声明中进行任何赋值。 (但是,如果您的构造函数分配字段,那么这是一个不同的故事。)

答案 2 :(得分:1)

在前两个之间唯一的区别是前者的意图更清晰。

虽然我知道bar1和bar2将被初始化为null(至少从概念上来说,希望它在两种情况下都得到优化),很明显意图是它们不是null而是设置为它们给出的值在构造函数中。

在第二种情况下,目的尚不清楚。开发人员明确地将它们设置为null,因此可能开发人员希望它们因某些原因而为空。然后开发人员将它们设置为唯一可见代码路径中的其他内容。当我看到无法理解意图的代码时,有四种可能性。

  1. 开发商是个白痴。
  2. 代码经历了一些更改,虽然有必要将显式设置设置为null,但它不再是,这只是早期代码的遗留问题。
  3. 开发犯了一个错误。
  4. 我没有发现什么。
  5. 我可以排除第一,因为我不和白痴一起工作。如果我发现自己和白痴一起工作,我会改善我的简历。

    我和其他三个人一起离开了。我并不傲慢,所以我不排除4,直到我确定。如果我不能快速询问有问题的开发人员,那么我将浪费一些时间来确保4不是这样的。如果我可以问开发者,我可能会浪费一些时间和他们的时间。不过,由于2,3和4,这并不是真的浪费,无论哪种方式,我都需要知道是哪种情况,因为只有这样我才能确定我理解代码并且没有与初始化相关的错误

    第三种情况要糟糕得多。假设一切顺利,那么唯一真正的影响是,编译器或抖动可能不会优化掉故意插入的残骸,这会产生非常轻微的性能影响。但是,由于一切都进展顺利,也许你只是更难找到一个bug。

    编辑:

    这假设对象创建没有副作用。如果有,那么第三种情况可能是从非常浪费到彻头彻尾的危险。

答案 3 :(得分:1)

因为已经建议1和2之间没有区别。只是提供一个明确指定'null'值的情况。

考虑,

public class Foo
    {
        ....
         public void DoSomething()
    {
        string someValue;

        if (someValue == null)
        {
            Console.WriteLine("SomeValue must not be null");
        }
        else
        {
            Console.WriteLine(someValue);
        }
    }
    }

您期望DoSomething的输出是什么? 这是一个编译时错误:'使用未分配的局部变量'somValue'。

因此,在这种情况下,它是强制性的,因此使someValue = null是有意义的。但是,对于成员字段,它不会,因为对象构造函数将默认值(默认值(T))分配给所有成员字段。