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

问题描述:

通常我有一个类这样:我应该将初始java字符串值从null设置为“”吗?

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

// etc etc etc 
} 

这使得FIELD1的和等于空的初始值FIELD2。将所有我的字符串类字段如下所示会更好吗?

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

// etc etc etc 
} 

然后,如果我符合类定义,我会避免大量的空指针问题。这种方法有什么问题?

+2

所以没有什么'坏'会发生,我只会失去我的Java纯度状态? – Martlark 2009-08-16 04:46:33

+0

当意外的“”字符串与引发的异常一样有用时,可以发现错误。有了这个优势,你的网络应用程序不会崩溃,让你难堪。 – Martlark 2010-07-14 00:10:43

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

在绝大多数情况下,空字符串和空字符串表示完全相同的东西 - 未知数据。无论您使用空字符串还是空字符串表示,都是一个选择问题。

+0

你能否请更新如果我们有像List这样的字符串以外的引用变量。应该用一些列表对象初始化它们以防止NPE – Killer 2017-03-27 09:47:19

+0

@Shubham,好点。集合(列表,集合,映射)是第二种情况,其中使用'空'版本而不是null通常是有意义的。就个人而言,我更喜欢(例如)一个空列表空引用。 – 2017-07-18 00:54:45

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

为了进一步解释:

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

正如Yuliy已经提到的,如果你看到了很多空指针异常的,那是因为你期待的事情有值时,他们不这样做,或者你做事马虎你使用之前初始化的东西他们。无论哪种情况,您都应该花时间进行正确编程 - 确保应具有值的事物具有这些值,并确保如果您访问的是可能没有价值的事物的值,那么将其纳入考虑范围。

+0

我同意;然而(只是作为魔鬼的拥护者),有些人习惯于松散类型的系统,他们可以开始使用未定义的字符串变量,并将其视为空。 – 2009-08-14 13:55:52

+0

同意,但有些原因可能会导致您初始化字符串。值得向海报解释两者的区别。 – doomspork 2009-08-14 13:56:26

+4

@Chris:但是Java并不是一种松散类型的语言,所以为什么还要花费一半的时间试图让它看起来像一个? – Tundey 2009-08-14 17:07:09

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

这种方式是疯狂(通常)。如果你遇到很多空指针问题,那是因为你在实际填充它们之前尝试使用它们。那些空指针问题是大声讨厌的警告警报,告诉你在哪里使用,让你进入并解决问题。如果你刚开始时将它们设置为空,那么你将冒着使用它们的风险,而不是你实际期望的。

+5

+1,但需要注意的一点是:如果从数据库填充对象,而该数据库恰好是Oracle,则将空字符串视为null。但是,明确地初始化为“”在这种情况下不会帮助你。 – kdgregory 2009-08-14 14:08:12

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

  1. 获得一个NullPointerException异常通常是您使用的是可变的,你应该是前很好的警示,或者说你忘了设置。将它设置为一个空字符串可以消除NullPointerException,但是可能会导致程序中的错误发生,从而导致不同的错误(并且难以追踪)。

  2. null和“”之间可以有一个有效的区别。空值通常表示没有设置值或值未知。一个空字符串表示它被故意设置为空。根据您的计划,这种微妙的差异可能很重要。

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

如果答案是肯定的,在声明中将其设置为“”是正确的做法。如果没有,这是一个让错误难以发现和诊断的秘诀。

没办法。你为什么想这样做?这会导致不正确的结果。空值和“”“不一样

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

如果你

私人字符串字段1 =“”;

您试图剿错误是很难找到的bug,后来

我不会建议。

相反,你应该给你的领域合理的价值观。如果他们不需要改变,我会让他们最终决定。

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

没有必要分配,我还没有初始化,但价值。只要给它初始值。

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

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而不是仅仅连接字符串,但我们都知道,对于某些代码来说,它只是简化了连接。

+5

有什么区别?他们看起来和我一样。 – Martlark 2011-05-03 23:33:21

我想当你使用String s = null时,它只会在堆栈上创建变量“s”,堆中不会存在任何对象,但只要你声明了一些东西就像String s =“”;它会做的就像它会在堆上创建对象一样。我们知道字符串是不可变的,所以每当你为字符串变量赋值时,它就会在堆上创建新的对象...所以我认为String s = null比String s =“”更有效率;

欢迎提出建议!!!!!

+0

不,因为String是不可变的,所以Java足够聪明,只能创建一个对象“”而只返回另一个对象的引用 – jasg 2017-03-31 13:57:47