为什么Java中没有String.Empty?

Tom*_*sky 237 java string

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

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

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

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

Noe*_*l M 175

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

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

更新
从您的评论到问题:

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

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

private static final String EMPTY_STRING = "";
Run Code Online (Sandbox Code Playgroud)

然后像在代码中一样引用它

TextBox.setText(EMPTY_STRING);
Run Code Online (Sandbox Code Playgroud)

至少你明确地想要一个空字符串,而不是忘记在IDE中填写String或类似的东西.

  • 我倾向于更喜欢string.empty,主要是因为它更明确.此外,在某些情况下,可能难以在视觉上区分""和"'"之类的事情.最后,正如其他人所指出的那样,当我们厌倦了真正的工作时,它只是那些无意义的风格事物中的一种,它们让我们争论.=) (73认同)
  • 我仍然会给你+1,但我觉得很脏,因为你提到了`StringBuilder`而没有谈论过十次九次使用`StringBuilder`而不是串联是完全不合适的. (10认同)

小智 113

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

  • @StephenC当我看到一个空的""时,我首先想到的是它是一个bug,有人没有完成函数等等.使用String.EMPTY我确切地知道开发人员想要返回一个空字符串. (57认同)
  • 看起来比空的""更好更容易阅读.我希望不只是我. (26认同)
  • @LakatosGyula这不仅仅是你.我从Java开始到.NET开发,而String.Empty是我很高兴在框架中找到的一个功能.我喜欢它在一组空引号上的显式特性. (14认同)
  • 对于 linter 说“使用命名常量而不是 blah blah blah”的所有那些时间也很有帮助。每个程序员都知道“”不是魔术,但不必向客户解释更好。 (4认同)
  • @LakatosGyula - 我认为可能是(只有你)。精通 Java 的程序员在阅读 `""` 时没有任何问题......并且*大多数*可能会大声反对使用 `EMPTY`,除非在 `EMPTY` 具有特定领域含义的特定情况下。(在这种情况下,可能有一个更合适的名称。) (3认同)

Pet*_*rey 27

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

if ("".equals(text))
Run Code Online (Sandbox Code Playgroud)

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

如果您认为存在性能优势,则应进行测试.如果你认为它不值得自己测试,这是一个很好的迹象,它真的不值得.

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

  • @AjoyBhatia问题是你可以创建新的空字符串.`if(""== new String())`为false.一个更好的测试`if(text.isEmpty())` (12认同)

dja*_*fan 9

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

String empty = org.apache.commons.lang.StringUtils.EMPTY;
Run Code Online (Sandbox Code Playgroud)

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


Fre*_*eit 7

Apache StringUtils也解决了这个问题.

其他选项的失败:

  • isEmpty() - 不安全.如果字符串为null,则抛出NPE
  • length()== 0 - 再次不是null安全.也没有考虑空格字符串.
  • 与EMPTY常量的比较 - 可能不是空的安全.空白问题

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

  • 所以...似乎唯一安全的选择是可怕的Yoda条件:`"".equals(s)`? (3认同)

Ben*_*ine 7

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

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

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

等等.


Sla*_*mir 6

不要只是说"字符串的内存池以字面形式重用,大小写关闭".编制者在幕后做的不是重点.这个问题是合理的,特别是考虑到收到的票数.

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


Don*_*ows 5

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

如果你真的想要一个EmptyString常数,那就自己动手吧.但它所做的只是鼓励更冗长的代码; 有将永远是任何利益这样做.

  • `x = String.Empty`比`x =""更好地传达意图.后者可能是偶然遗漏.要说*从来没有*任何好处是不正确的. (25认同)