我应该将Java字符串的初始值从null设置为“”吗?

50

通常我有这样一个类:

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
}

如果我在类定义上保持一致,那么我将避免很多空指针问题。这种方法有哪些问题?


4
所以并不会发生什么“坏事”,我只是会失去我的Java纯洁状态吗? - Martlark
当使用意外的“”字符串时,错误就会被发现,这与引发异常同样有用。这样做的好处是您的Web应用程序不会崩溃并使您尴尬。 - Martlark
11个回答

78

那样会导致疯狂(通常情况下)。如果你遇到了很多空指针问题,那是因为你在实际填充之前尝试使用它们。这些空指针问题就像响亮的警报声一样告诉你使用它们的位置,让你可以进去修复问题。如果你最初只将它们设置为空,那么你将冒着使用它们而不是实际期望值的风险。


5
+1,但有一个警告:如果你从数据库中填充对象,而该数据库恰好是Oracle,则空字符串会被视为null。然而,在这种情况下,明确初始化为""也无法帮助你。 - kdgregory
这个答案很棒。 - igracia

57

绝对不是。一个空字符串和一个null字符串完全不同,您不应混淆它们。

进一步解释:

  • "null"的意思是"我还没有初始化此变量,或者它没有值"
  • "空字符串"的意思是"我知道这个值是什么,就是空的"

正如Yuliy已经提到的那样,如果您看到很多空指针异常,那是因为您期望它们有值,但它们实际上没有值,或者在使用之前初始化不当。无论哪种情况,您都应该花时间正确地编程 - 确保应该具有值的内容确实具有这些值,并确保如果访问可能没有值的内容的值,您会考虑到这一点。


我同意;然而(只是为了做个恶魔的代言人),有些人习惯于松散类型的系统,在这种系统中,他们可以随意使用未定义的字符串变量,而它会被视为空。 - C. K. Young
同意,但是你可能希望初始化你的字符串,这其中有一些原因。或许值得向发帖者解释一下两者之间的区别。 - doomspork
5
@Chris:但Java并不是一种弱类型语言,那么为什么还要费尽心思地试图让它看起来像一个弱类型语言呢? - Tundey

13

在某些情况下,在值被设置在其他位置之前使用它并作为空字符串的行为是否有意义?也就是说,空字符串实际上是否是正确的默认值,是否有必要设置默认值?

如果答案是肯定的,那么在声明中将其设置为""是正确的做法。否则,这会使错误更难以发现和诊断。


11

我不同意其他帖子的观点。使用空字符串是可以接受的。我尽可能喜欢使用它。

在绝大多数情况下,空字符串和null字符串代表完全相同的含义-未知数据。你用null或空字符串来表示这个是一个选择问题。


请问您能否更新一下,如果我们除了String之外还有引用变量,比如List,是否需要使用某个list对象进行初始化,以防止NPE错误。 - Shubham AgaRwal
1
@Shubham,说得好。集合(列表、集合、映射)是第二种情况,在这种情况下使用“empty”版本而不是null通常是有意义的。就个人而言,我更喜欢(例如)一个空列表而不是一个null引用。 - John

7

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

  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
有什么不同吗?我觉得它们看起来一样。 - Martlark

7

一般最好避免这样做。原因如下:

  1. 得到NullPointerException通常是一个很好的警告,说明你在使用变量之前应该使用它,或者你忘记设置它了。将其设置为空字符串会消除NullPointerException,但可能会在程序后面引起不同的(更难追踪)错误。

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


5
我建议都不选。
相反,你应该给你的字段赋予明智的值。如果它们不需要改变,我会将它们定义为 final。
public class Foo { 
    private final String field1; 
    private final String field2;
    public Foo(String field1, String field2) {
       this.field1 = field1;
       this.field2 = field2;
    }
    // etc. 
} 

不需要分配"未初始化值",只需给它初始值即可。


1

我建议避免这样做,你需要知道你的实例是否正确地填充了数据。


1

不行。你为什么要这样做?那会导致错误的结果。null和""""是不同的。


1

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

如果您执行以下操作

private String field1 = "";

您正在试图抑制错误。稍后很难找到错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接