我应该使用string.isEmpty()还是"".equals(string)?

176

我通常会与string == null一起测试,因此我并不真的关心一个安全的空值测试。那么我应该使用哪个?


我通常会和“字符串== null”一起测试,所以我不太关心安全的空值测试。我应该使用哪一个?
String s = /* whatever */;
...
if (s == null || "".equals(s))
{
    // handle some edge case here
}

或者

if (s == null || s.isEmpty())
{
    // handle some edge case here
}

在此提醒一下 - isEmpty() 方法是否除了 return this.equals(""); 或者 return this.length() == 0; 之外还有其他功能呢?


27
请记住,isEmpty() 仅适用于 Java 6 及以上版本。 - ColinD
1
你可以创建一个辅助方法 Util.String.hasValue(String s),它可以检查 null、空字符串和空格,以处理所有情况。 - Cloudanger
5
可能不是问题- J2SE 5.0 已经在一段时间前结束了其服务生命周期。 - Tom Hawtin - tackline
1
另一个需要考虑的问题是 "".equals() 接受 Object 作为参数,因此如果参数类型从 String 更改为其他类型,则不会出现编译器错误,这可能好也可能坏。 - Paul Jackson
6个回答

253
< p > "".equals(s) 的主要优点是您不需要进行 null 检查(equals 会检查其参数,如果为 null,则返回 false),而您似乎不关心这个。如果您不担心 s 是否为 null(或正在检查它),我绝对会使用 s.isEmpty();它显示了您正在检查的内容,即您是否关心 s 是否为空字符串,而不仅仅是等于空字符串。


30
谢谢解释。现在我知道为什么要偏爱 "".equals(str) 而不是 str.equals("")!我一直想知道为什么其他人经常使用它,但没有考虑到空值。太好了 :-) - Peter Wippermann
10
在我看来,以上示例中仍然需要进行空值检查,因为我们假设该条件对空值应为真。s == null || "".equals(s) - mkorpela
5
不,如果getValue()返回了null,在调用toString()时会导致空指针异常。 - ataulm
12
并没有涉及任何魔法。如果s是null,你就不能调用它的方法——因为它是null。""永远不会是null,所以你可以安全地调用它的方法,并且equals()可以处理其参数为null的情况。 - Michael Mrozek
5
关于性能的说明:isEmpty() 方法检查一个私有数组的内部长度,而 equals(Object anObject) 方法则做了更多的工作(例如检查 instanceof)。就性能而言,isEmpty() 方法通常更快。 - Turing85
显示剩余2条评论

84

String.equals("") 比起直接调用 isEmpty() 函数要稍微慢一些。因为字符串是不可变的,所以它们在构造函数中初始化了一个计数变量。

isEmpty() 函数将计数变量与 0 进行比较,而 equals 函数则会检查类型、字符串长度,如果匹配,则会迭代字符串进行比较。

因此,回答你的问题,isEmpty() 的操作要少得多!这是一件好事。


3
在这种情况下,我认为差异并不适用;因为字符串的大小不匹配(除非字符串实际上为空,此时没有字符可供迭代比较),所以永远不会有对字符串进行迭代比较的情况。 - Michael Mrozek
2
使用“==”进行比较时,只需进行简单的引用检查即可。但是,如果使用“equals”,则首先需要进行引用检查以查看它们是否为同一对象,然后进行instanceof检查,接着进行String类型转换、长度检查,最后才进行迭代。如果两个字符串都为空,则只需进行简单的引用检查即可。 - David Young
String类的源代码可以在http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Core/lang/java/lang/String.java.htm获取。 - David Young
1
@David 链接失效了;这是有效的链接 http://www.docjar.com/html/api/java/lang/String.java.html#1011 - Matt Ball

17

除了提到的其他问题之外,您可能需要考虑的一件事是isEmpty()是在1.6中引入的,因此如果您使用它,就无法在Java 1.5或更低版本上运行代码。


4
那绝对不是我担心的事情。 - Matt Ball
1
此外,这个回答已经是6年前的事了。我希望没有人需要再使用像Java 1.5这样古老的东西了。 - Misha Nasledov
1
实际上,在升级Java版本时可能会出现许多问题。对于在大型服务器上运行的后端应用程序来说,这并不是很关键,但对于客户端应用程序来说却很重要。图形库和垃圾回收策略通常会受到主要和次要Java升级的影响。此外,客户端软件可以在各种操作系统上运行,有时内存有限,这意味着您通常没有预算/资源来测试所有内容。- 是的,我有客户在2017年仍然坚持使用Java 5。 - bvdb

15

你可以使用Apache Commons StringUtils的isEmpty()或isNotEmpty()方法。


2
@2019 年了,我们仍然需要第三方库来完成这个任务 :叹气: - Adam

3
我写了一个Tester类,可以测试性能:
public class Tester
{
    public static void main(String[] args)
    {
        String text = "";

        int loopCount = 10000000;
        long startTime, endTime, duration1, duration2;

        startTime = System.nanoTime();
        for (int i = 0; i < loopCount; i++) {
            text.equals("");
        }
        endTime = System.nanoTime();
        duration1 = endTime - startTime;
        System.out.println(".equals(\"\") duration " +": \t" + duration1);

        startTime = System.nanoTime();
        for (int i = 0; i < loopCount; i++) {
            text.isEmpty();
        }
        endTime = System.nanoTime();
        duration2 = endTime - startTime;
        System.out.println(".isEmpty() duration "+": \t\t" + duration2);

        System.out.println("isEmpty() to equals(\"\") ratio: " + ((float)duration2 / (float)duration1));
    }
}

我发现使用.isEmpty()的时间大约是.equals("")时间的一半。


这不是一个有效的微基准测试。我强烈建议使用Caliper或类似的专用基准测试工具。https://dev59.com/hHRB5IYBdhLWcg3wz6UK - Matt Ball
谢谢你的建议!等我有空了,我会尝试一些微基准测试并更新我的答案。 - bonapart3

2

这并不重要。在我看来,"".equals(str) 更加清晰明了。

isEmpty() 返回 count == 0


48
我认为 str.isEmpty()"".equals(str) 更清晰明了,它表达了你要检查的内容。虽然这是一种个人观点。 - ColinD
7
有些人喜欢使用"".equals(str)来避免NPE。我个人不太喜欢这种方法,因为我宁愿先检查字符串不为空。 - CoolBeans
@CoolBeans 是的。不过问题说:所以我并不真的关心空安全测试. - Valerio Bozz

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