2012-01-14 85 views
2

是否有之间的差异(在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。对于字符串,我明白分配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; 
    } 
} 
+1

Uuughh当他们说他们的老板坚持这个或那个没有任何区别的编程细节时,我感到非常糟糕。作为一名初级程序员进行月光照明的开发经理,并讨论无用的语义。不要忍受它,姐妹和兄弟。 – 2012-01-14 02:45:03

+0

实际上,我不明白分配'str =“”',除非有充分理由说它应该是空字符串。至少如果你错过了将它从null改为bug的话,这个bug可能会更快。或者一个字符串应该是空的,或者它不应该,随机地抛出'=“”'只是破坏。 – 2012-01-14 03:09:12

回答

4

没有必要明确初始化实例变量为默认值。在Java和C#中,实例变量在创建实例时被赋予默认值。参考类型已在运行构造函数的主体之前为 null。 int已经是0等等。在第一个代码片段中,bar1和bar2已经是空的。没有需要明确说明它,如在第二个片段。

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

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

+0

如果您有多个构造函数,或者没有立即从构造函数中分配所有值,这是否会更改? – Cody 2012-01-14 02:36:17

+0

我已经扩大了答案(并且删除了关于单个构造函数的措词),希望能够使其更清晰。实例成员总是初始化为默认值,您不必明确地执行此操作。 – 2012-01-14 02:43:52

2

如果您要在构造函数中指定一个类字段,通常不会在字段声明中进行任何赋值。 (如果你的构造分配领域,虽然,这是一个不同的故事。)

1

前两个之间的唯一区别是,为了前者是意图更加清晰。

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

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

  1. 开发者是个白痴。
  2. 代码经历了一些变化,虽然显式设置为null是必要的,但它不再是,而这只是早期代码的遗留问题。
  3. 开发出了一个错误。
  4. 我没有发现什么。

我可以排除数字1,因为我不适合白痴。如果我发现自己在与白痴打交道,我会抛光我的简历。

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

第三种情况更糟糕。假设一切顺利,那么唯一真正的效果就是编译器或抖动不会优化掉故意插入的cruft,这会对性能造成很小的影响。但是,因为一切都不顺利,也许你刚刚发现了一个难以发现的错误。

编辑:

这是假设,有没有副作用创建对象。如果有的话,那么第三种情况可能是从相当浪费到彻底危险的事情。

1

由于已经提示1和2之间没有区别,只需要提供明确指定'空'值的情况。

考虑,

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))。

相关问题