为什么Java中没有String.Empty?

为什么Java中没有String.Empty?,java,string,Java,String,我知道,每次我键入字符串文字“”,字符串池中都会引用相同的字符串对象 但是为什么stringapi不包含一个公共静态最终字符串Empty=“”,因此我可以使用对字符串的引用。空的 它至少可以节省编译时间,因为编译器知道引用现有字符串,而不必检查它是否已经被创建以供重用,对吗?就我个人而言,我认为字符串文字的激增,尤其是微小的文字,在许多情况下是一种“代码气味” 那么,没有String.Empty的背后是否有一个伟大的设计原因,或者语言创建者根本没有分享我的观点呢?String.Empty是12个

我知道,每次我键入字符串文字
”,字符串池中都会引用相同的字符串对象

但是为什么stringapi不包含一个
公共静态最终字符串Empty=“”
,因此我可以使用对
字符串的引用。空的

它至少可以节省编译时间,因为编译器知道引用现有字符串,而不必检查它是否已经被创建以供重用,对吗?就我个人而言,我认为字符串文字的激增,尤其是微小的文字,在许多情况下是一种“代码气味”


那么,没有String.Empty的背后是否有一个伟大的设计原因,或者语言创建者根本没有分享我的观点呢?

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

特别是考虑到
String
s是不可变的,您不可能首先获取一个空字符串,然后对其执行一些操作-最好使用
StringBuilder
(或者
StringBuffer
,如果您希望线程安全)并将其转换为字符串

更新
根据您对问题的评论:

实际上是什么启发了这一切
TextBox.setText(“”)

我相信在您的适当班级中提供常数是完全合法的:

private static final String EMPTY_STRING = "";
然后在代码中引用它作为

TextBox.setText(EMPTY_STRING);
通过这种方式,至少您明确表示您想要一个空字符串,而不是忘记在IDE中填写字符串或类似的内容。

所有这些
文本都是相同的对象。为什么要让这些额外的复杂性?它只是输入的时间更长,而且不太清晰(编译器的成本很低)。因为Java的字符串是不可变的对象,所以根本不需要区分它们,除非可能是为了提高效率,但对于空字符串文本来说,这没什么大不了的

如果你真的想要一个
EmptyString
常量,你自己做吧。但它所能做的只是鼓励编写更冗长的代码;这样做永远不会有任何好处。

我知道,每次我键入字符串文字“”,字符串池中都会引用相同的字符串对象。
没有这样的保证。您不能在应用程序中依赖它,这完全取决于jvm

还是语言创作者根本不同意我的观点?

是的。对我来说,这似乎是一件优先级很低的事情。

Apache StringUtils也解决了这个问题

其他选项的缺点:

  • isEmpty()-非空安全。如果 字符串为空,抛出一个NPE
  • length()==0-同样不是空安全的。 也不考虑 空白字符串
  • 与空常量的比较-可能 不能是空安全的。空白问题

诚然StringUtils是另一个可以拖拽的库,但它工作得非常好,可以节省大量的时间和麻烦来检查空值或优雅地处理NPE。

要补充Noel M所说的内容,你可以看看这个问题,这个答案表明常量被重用了

字符串常量总是“插入” 因此,实际上没有必要这样做 不变的

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

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

同样,你可以创建零,一个int常量。。。这在Integer类中不存在,但正如我所评论的,写和读都会很痛苦:

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

等等。

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

if ("".equals(text))
最终你应该做你认为最清楚的事情。大多数程序员认为“”表示空字符串,而不是一个忘记输入任何内容的字符串

如果您认为有性能优势,您应该测试它。如果你认为它不值得你自己去测试,这是一个很好的迹象,表明它真的不值得

这听起来像是你试图解决一个问题,而这个问题在15年前设计语言时就已经解决了。

对于那些声称
字符串的人来说。空的
可以互换,或者
更好,你大错特错了

每次您执行类似myVariable=“”;您正在创建对象的实例。 如果Java的字符串对象有一个空的公共常量,则该对象只有一个实例“”

例如:-

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个对象的指针

或:-

10个指针指向10个对象

这是低效的,而且在整个大型应用程序中,这可能非常重要


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

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

不要只说“字符串的内存池是以文本形式重用的,大小写是封闭的”。编译器在后台做什么并不是这里的重点。这个问题是合理的,特别是考虑到它收到的投票数

这是关于对称性的,没有它,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()

迟交的答案,但我认为它增加了一些东西
myVar0 = "";
myVar1 = "";
myVar2 = "";
myVar3 = "";
myVar4 = "";
myVar5 = "";
myVar6 = "";
myVar7 = "";
myVar8 = "";
myVar9 = "";
String empty = org.apache.commons.lang.StringUtils.EMPTY;