(在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;
}
}
答案 0 :(得分:4)
无需将实例变量显式初始化为默认值。在Java和C#中,在创建实例时为实例变量分配默认值。在构造函数运行的主体之前,引用类型已经 null。 int
已经是0等。在第一个代码段中,bar1和bar2已经为空。没有需要来明确说明它,就像在第二个片段中一样。
在第二个示例(第三个代码段)中,如果你所做的只是用构造函数中的另一个引用覆盖,则绝对不需要将实例变量实例化为new Bar1();
。
当构造函数尚未使用提供的参数立即覆盖默认值时,您可能希望将成员变量初始化为值,而默认值应该是类型默认值以外的值。但将其设置为默认值只是多余的。但是,如果它可以帮助您的老板或团队的其他成员了解这些默认值是什么,那么就这样吧。
答案 1 :(得分:2)
如果您要在构造函数中指定一个类字段,通常没有充分的理由在字段声明中进行任何赋值。 (但是,如果您的构造函数不分配字段,那么这是一个不同的故事。)
答案 2 :(得分:1)
在前两个之间唯一的区别是前者的意图更清晰。
虽然我知道bar1和bar2将被初始化为null(至少从概念上来说,希望它在两种情况下都得到优化),很明显意图是它们不是null而是设置为它们给出的值在构造函数中。
在第二种情况下,目的尚不清楚。开发人员明确地将它们设置为null,因此可能开发人员希望它们因某些原因而为空。然后开发人员将它们设置为唯一可见代码路径中的其他内容。当我看到无法理解意图的代码时,有四种可能性。
我可以排除第一,因为我不和白痴一起工作。如果我发现自己和白痴一起工作,我会改善我的简历。
我和其他三个人一起离开了。我并不傲慢,所以我不排除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))分配给所有成员字段。