设置和实例化类级变量的正确方法是什么
本文关键字:方法 是什么 变量 实例化 设置 | 更新日期: 2023-09-27 18:20:20
(在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;
}
}
不需要显式地将实例变量初始化为默认值。在Java和C#中,在创建实例时,实例变量被分配默认值。在构造函数的主体运行之前,引用类型已为null。int
已经是0,等等。在第一个代码片段中,bar1和bar2已经为null。没有需要来显式声明它,如第二个片段中所示。
在第二个示例(第三个片段)中,如果您所做的只是用构造函数中的另一个引用重写,那么绝对不需要将实例变量实例化为new Bar1();
。
当默认值应该不是类型的默认值时,当构造函数尚未立即用提供的参数覆盖它时,您可能希望将成员变量初始化为值。但将其设置为默认值是多余的。然而,如果它能帮助你的老板或团队的其他成员了解这些默认值是什么,那就顺其自然吧
如果要在构造函数中分配类字段,通常没有充分的理由在字段声明中进行任何分配。(不过,如果构造函数没有分配字段,那就另当别论了。)
因为已经有人建议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是有意义的。但是,对于成员字段,它并不是这样,因为对象构造函数为所有成员字段分配默认值(default(T))。
前两者之间唯一的区别是前者的意图更清晰。
虽然我知道bar1和bar2将被初始化为null(至少在概念上,希望在这两种情况下都能得到优化),但很明显,目的是它们不是null,而是设置为构造函数中给定的值。
然而,在第二种情况下,其意图并不明确。开发人员明确地将它们设置为null,因此开发人员可能出于某种充分的原因希望它们为null。然后,开发人员将它们设置为唯一可见代码路径中的其他内容。当我看到无法理解其意图的代码时,有四种可能性。
- 开发人员是个白痴
- 代码经历了一些更改,虽然一旦显式设置为null是必要的,但它就不再是了,这只是早期代码的遗留问题
- 开发犯了一个错误
- 我没发现什么
我可以排除第1个,因为我不和白痴一起工作。如果我发现自己和白痴一起工作,我会完善我的简历。
剩下我和其他三个人在一起。我并不傲慢,所以在确定之前我不排除4分。如果我不能很快询问开发人员的问题,那么我将浪费一些时间来确保4不是这样。如果我可以问开发人员,我可能会浪费我和他们的一些时间。尽管如此,这并不是因为2、3和4而浪费,无论哪种方式,我都需要知道是哪种情况,因为只有这样我才能确保我理解代码,并且没有与初始化相关的错误。
第三种情况更糟。假设一切顺利,那么唯一真正的影响是编译器或抖动可能不会优化掉故意插入的cruft,这会对性能产生非常轻微的影响。但是,既然一切都不顺利,也许你只是让一个bug更难找到。
编辑:
这假设创建对象没有副作用。如果有的话,那么第三种情况可能从相当浪费到完全危险。