【问题标题】:Should I set the initial java String values from null to ""?我应该将初始 java 字符串值从 null 设置为“”吗?
【发布时间】:2010-11-19 15:53:49
【问题描述】:

我经常有这样的课程:

public class Foo
{
private String field1;
private String field2;

// etc etc etc
}

这使得 field1 和 field2 的初始值等于 null。让我的所有 String 类字段如下所示会更好吗?

public class Foo
{
private String field1 = "";
private String field2 = "";

// etc etc etc
}

然后,如果我与类定义一致,我会避免很多空指针问题。这种方法有什么问题?

【问题讨论】:

  • 所以不会发生任何“坏事”,我会失去我的 Java 纯度状态吗?
  • 当使用意外的 "" 字符串与引发的异常一样有用时,会发现错误。凭借这样的优势,您的 Web 应用不会崩溃或让您难堪。

标签: java null initialization string


【解决方案1】:

那样就是疯狂(通常)。如果您遇到很多空指针问题,那是因为您在实际填充它们之前尝试使用它们。那些空指针问题是响亮的令人讨厌的警告警报器,告诉您使用的位置,然后让您进入并解决问题。如果您最初只是将它们设置为空,那么您将冒着使用它们而不是您实际期望的风险的风险。

【讨论】:

  • +1,但有一点需要注意:如果您从数据库中填充对象,并且该数据库恰好是 Oracle,则空字符串将被视为 null。但是,在这种情况下,显式初始化为 "" 对您没有帮助。
【解决方案2】:

绝对不是。空字符串和空字符串是完全不同的东西,你不应该混淆它们。

进一步解释:

  • “null”表示“我还没有初始化 这个变量,或者它没有值”
  • “空字符串”的意思是“我知道值是什么,它是空的”。

正如 Yuliy 已经提到的,如果您看到很多空指针异常,那是因为您期望事物具有值而实际上它们没有值,或者您在使用它们之前对初始化事物感到草率。在任何一种情况下,您都应该花时间正确编程 - 确保应该具有值的事物具有这些值,并确保如果您正在访问可能没有价值的事物的值,您会考虑到这一点。

【讨论】:

  • 我同意;但是(只是为了成为魔鬼的拥护者)有些人习惯于松散类型的系统,他们可以开始使用未定义的字符串变量并将其视为空。
  • 同意,但是您可能希望初始化字符串是有原因的。可能值得向发布者解释两者的区别。
  • @Chris:但是 Java 不是一种松散类型的语言,所以为什么还要费心费力地尝试让它看起来像一个呢?
【解决方案3】:

在特定情况下,在将值设置到其他位置之前使用该值并在这种情况下表现为空字符串是否真的有意义?即一个空字符串实际上是一个正确的默认值,并且有一个默认值是否有意义?

如果答案是肯定的,那么在声明中将其设置为 "" 是正确的做法。如果不是这样,那就是让错误更难发现和诊断的秘诀。

【讨论】:

    【解决方案4】:

    我不同意其他海报。使用空字符串是可以接受的。我更喜欢尽可能使用它。

    在大多数情况下,空字符串和空字符串表示完全相同的东西——未知数据。是否用 null 或空 String 表示它是一个选择问题。

    【讨论】:

    • 如果我们有像 List 这样的 String 以外的引用变量,你能更新一下吗?应该用一些列表对象初始化它们以防止 NPE
    • @Shubham,说得好。集合(list、set、map)是第二种情况,在这种情况下,使用“空”版本而不是 null 通常是有意义的。就我个人而言,我更喜欢(例如)一个空列表而不是一个空引用。
    【解决方案5】:

    通常最好避免这种情况。几个原因:

    1. 获取 NullPointerException 通常是一个很好的警告,表明您在使用之前使用了一个变量,或者您忘记了设置它。将其设置为空字符串会消除 NullPointerException,但可能会在程序中进一步导致不同的(并且更难追踪)错误。

    2. null 和“”之间可能存在有效差异。空值通常表示未设置任何值或该值未知。空字符串表示它被故意设置为空。根据您的程序,这种细微差别可能很重要。

    【讨论】:

      【解决方案6】:

      我知道这是一个老问题,但我想指出以下几点:

        String s = null;
      
        s += "hello";
        System.out.println(s);// this will return nullhello
      

        String s = "";
      
        s += "hello";
        System.out.println(s); // this will return hello
      

      显然,这个问题的真正答案是应该使用 StringBuffer 而不是仅仅连接字符串,但我们都知道,对于某些代码来说,连接起来更简单。

      【讨论】:

      • 有什么区别?它们在我看来是一样的。
      【解决方案7】:

      我都不建议。

      相反,您应该为您的字段提供合理的值。如果它们不必更改,我会将它们定为最终版本。

      public class Foo { 
          private final String field1; 
          private final String field2;
          public Foo(String field1, String field2) {
             this.field1 = field1;
             this.field2 = field2;
          }
          // etc. 
      } 
      

      无需分配,我还没有初始化值。只需给它初始值。

      【讨论】:

        【解决方案8】:

        我会避免这样做,您需要知道您的实例是否没有正确填充数据。

        【讨论】:

          【解决方案9】:

          Null 更好,这就是为什么它们被称为未经检查的异常{Null 指针异常}。抛出异常时,它会告诉您必须在调用任何方法之前将其初始化为某个非空值。

          如果你这样做了

          私有字符串字段1 = "";

          您正在尝试抑制错误。以后很难找到bug。

          【讨论】:

            【解决方案10】:

            我认为,当您使用 String s = null 时,它只会在堆栈上创建变量“s”,并且堆上不会存在任何对象,但只要您声明类似 String s="";它所做的就像它将在堆上创建“”对象。我们知道字符串是不可变的,所以每当你每次为字符串变量分配新值时,它都会在堆上创建新对象......所以我认为 String s=null比 String s = "";

            高效

            欢迎提出建议!!!!!!

            【讨论】:

            • 不,因为 String 是不可变的,Java 足够聪明,只创建对象 "" 一次,然后返回另一个对它的引用
            【解决方案11】:

            没办法。你为什么要这样做?这将给出不正确的结果。 nulls 和 """ 不一样。

            【讨论】:

              猜你喜欢
              • 2017-06-06
              • 2012-07-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-03-19
              • 1970-01-01
              • 2021-04-01
              相关资源
              最近更新 更多