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

本文关键字:方法 是什么 变量 实例化 设置 | 更新日期: 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。然后,开发人员将它们设置为唯一可见代码路径中的其他内容。当我看到无法理解其意图的代码时,有四种可能性。

  1. 开发人员是个白痴
  2. 代码经历了一些更改,虽然一旦显式设置为null是必要的,但它就不再是了,这只是早期代码的遗留问题
  3. 开发犯了一个错误
  4. 我没发现什么

我可以排除第1个,因为我不和白痴一起工作。如果我发现自己和白痴一起工作,我会完善我的简历。

剩下我和其他三个人在一起。我并不傲慢,所以在确定之前我不排除4分。如果我不能很快询问开发人员的问题,那么我将浪费一些时间来确保4不是这样。如果我可以问开发人员,我可能会浪费我和他们的一些时间。尽管如此,这并不是因为2、3和4而浪费,无论哪种方式,我都需要知道是哪种情况,因为只有这样我才能确保我理解代码,并且没有与初始化相关的错误。

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

编辑:

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