为什么Java中没有String.Empty?

时间:2010-08-10 15:27:19

标签: java

据我所知,每次输入字符串文字""时,字符串池中都会引用相同的String对象。

但为什么String API不包含public static final String Empty = "";,所以我可以使用对String.Empty的引用?

它至少会节省编译时间,因为编译器会知道引用现有的String,而不必检查它是否已经被创建以供重用,对吧?我个人认为,在许多情况下,字符串文字的扩散,特别是小字符串,是一种“代码味道”。

那么没有String.Empty背后有一个大设计理由,还是语言创作者根本没有分享我的观点?

13 个答案:

答案 0 :(得分:169)

String.EMPTY是12个字符,""是2个,它们在运行时都会在内存中引用完全相同的实例。我不完全确定为什么String.EMPTY会节省编译时间,事实上我认为它会是后者。

特别是考虑到String是不可变的,它不像你可以先得到一个空字符串,并对其执行一些操作 - 最好使用StringBuilder(或StringBuffer如果你想要是线程安全的,并把它变成一个字符串。

<强>更新
从您的评论到问题:

  

实际上是什么启发了这一点   TextBox.setText("");

我认为在适当的班级中提供一个常数是完全合法的:

private static final String EMPTY_STRING = "";

然后在代码中引用它

TextBox.setText(EMPTY_STRING);

通过这种方式,至少你明确表示你想要一个空字符串,而不是忘记在IDE中填写String或类似的东西。

答案 1 :(得分:99)

使用org.apache.commons.lang.StringUtils.EMPTY

答案 2 :(得分:25)

如果要与空字符串进行比较而不必担心空值,可以执行以下操作。

if ("".equals(text))

最终你应该做你认为最清楚的事情。大多数程序员认为“”表示空字符串,而不是某个忘记放入任何内容的字符串。

如果您认为有性能优势,则应进行测试。如果你认为它不值得自己测试,那么这是一个很好的迹象,它确实不值得。

听起来你试图解决15年前设计语言时解决的问题。

答案 3 :(得分:7)

Apache StringUtils也解决了这个问题。

其他选项的失败:

  • isEmpty() - 不安全。如果 string为null,抛出NPE
  • length()== 0 - 再次不是null安全。 也没有考虑到 空白字符串。
  • 与EMPTY常数的比较 - May 不是空的安全。空白问题

Granted StringUtils是另一个可以拖动的库,但它运行良好,可以节省大量时间,并且可以轻松检查空值或优雅地处理NPE。

答案 4 :(得分:7)

如果您确实需要String.EMPTY常量,则可以在项目中创建名为“常量”(例如)的实用程序静态最终类。这个类将维护你的常量,包括空字符串......

在同样的想法中,你可以创建在Integer类中不存在的ZERO,ONE int常量......但是就像我评论的那样,编写和阅读会很痛苦:

for(int i=Constants.ZERO; ...) {
    if(myArray.length > Constants.ONE) {
        System.out.println("More than one element");
    }
}

答案 5 :(得分:5)

所有这些""文字都是同一个对象。为什么要做所有额外的复杂性?键入的时间更长,更不清晰(编译器的成本最低)。由于Java的字符串是不可变对象,因此除了可能作为效率之外,根本不需要区分它们,但使用空字符串文字并不是什么大问题。

如果你真的想要EmptyString常数,请自己动手。但它所做的只是鼓励更冗长的代码;这样做永远不会有任何好处。

答案 6 :(得分:5)

不仅要说“字符串存储池以原义形式重用,而且大小写已关闭”。编译器在幕后所做的不是重点。这个问题是合理的,特别是考虑到收到的赞成票数。

这与对称性有关,如果没有它,API将更难用于人类。众所周知,早期的Java SDK忽略了该规则,现在为时已晚。这是我脑海中的几个例子,您可以随意使用“最喜欢的”例子:

  • BigDecimal.ZERO,但没有AbstractCollection.EMPTY,String.EMPTY
  • Array.length但List.size()
  • List.add(),Set.add()但是Map.put(),ByteBuffer.put(),我们别忘了StringBuilder.append(),Stack.push()

答案 7 :(得分:3)

要添加Noel M所说的内容,你可以看一下这个问题,这个答案表明常量被重用了。

http://forums.java.net/jive/message.jspa?messageID=17122

  

字符串常量总是“实习”   所以没有必要这样做   恒定。

String s=""; String t=""; boolean b=s==t; // true

答案 8 :(得分:2)

据我所知,每次输入字符串文字“”时,字符串池中都会引用相同的String对象。
没有这样的保证。你不能在你的应用程序中依赖它,完全由jvm来决定。

或语言创作者根本不同意我的观点?
是的。对我来说,这似乎是非常低优先级的事情。

答案 9 :(得分:2)

最新答案,但我认为它为该主题添加了一些新内容。

以前的答案都没有回答原始问题。有些人试图证明缺乏常数是合理的,而另一些人则展示了我们应对常数缺乏的方法。但是,没有人为常量的利益提供令人信服的理由,因此仍然缺乏适当的解释。

一个常量很有用,因为它可以防止某些代码错误不被注意。

假设您有一个庞大的代码库,其中包含数百个对“”的引用。有人在滚动代码时修改了其中之一,并将其​​更改为“”。这样的更改很可能会被忽视而无法投入生产,这时可能会导致某些问题,其来源很难发现。

OTOH,一个名为EMPTY的库常量,如果遇到相同的错误,将为EM PTY之类的生成编译器错误。

定义自己的常量仍然更好。仍然有人可能会错误地更改其初始化,但是由于其用途广泛,因此与单个用例中的错误相比,更难以发现这种错误的影响。

这是使用常量而不是文字值所获得的一般好处之一。人们通常会认识到,将常量用于数十个位置中的值可以使您仅在一个位置中轻松更新该值。鲜为人知的是,这也防止了该值被意外修改,因为这种更改会在所有地方显示。因此,是的,“”比EMPTY短,但使用EMPTY比“”更安全。

因此,回到最初的问题,我们只能推测语言设计人员可能没有意识到为经常使用的文字值提供常量的好处。希望有一天,我们会看到Java中添加的字符串常量。

答案 10 :(得分:0)

很有趣的是,它有多老了,仍然没有像C#中那样好的字符串类。 我从事Java已有几年了,但我仍然也从事c#。当我使用Java时,我会错过字符串的C#语言的完整性。 主要是我想念string.Empty和string.IsNullOrEmpty(string)。 我也真的很想念小写的字符串类型。

++++ 1,用于将这些东西添加到Java中。所有的变通办法就是这样。 2020年及以后的快乐编码!

答案 11 :(得分:0)

这似乎是显而易见的答案:

String empty = org.apache.commons.lang.StringUtils.EMPTY;

很棒,因为“空初始化”代码不再有“魔法字符串”并使用常量。

答案 12 :(得分:-13)

对于那些声称""String.Empty可以互换或""更好的人,你就错了。

每次你做像myVariable =“”这样的事情;您正在创建对象的实例。 如果Java的String对象具有EMPTY公共常量,则只有1个对象实例“

例如: -

String.EMPTY = ""; //Simply demonstrating. I realize this is invalid syntax

myVar0 = String.EMPTY;
myVar1 = String.EMPTY;
myVar2 = String.EMPTY;
myVar3 = String.EMPTY;
myVar4 = String.EMPTY;
myVar5 = String.EMPTY;
myVar6 = String.EMPTY;
myVar7 = String.EMPTY;
myVar8 = String.EMPTY;
myVar9 = String.EMPTY;

10(11包括String.EMPTY)指向1个对象的指针

或者: -

myVar0 = "";
myVar1 = "";
myVar2 = "";
myVar3 = "";
myVar4 = "";
myVar5 = "";
myVar6 = "";
myVar7 = "";
myVar8 = "";
myVar9 = "";

指向10个对象的10个指针

这是低效的,在整个大型应用程序中,可能很重要。

也许Java编译器或运行时的效率足以自动将“”的所有实例指向同一个实例,但它可能不会并需要额外的处理才能做出决定。