杰瑞科技汇

java 判断string相等

你必须分清楚两种“相等”的含义:

  1. 内容相等 (值相等):两个字符串对象包含的字符序列完全相同。"hello""hello"
  2. 引用相等 (对象相等):两个变量指向内存中的同一个 String 对象。String s1 = new String("abc"); String s2 = s1;

下面我们详细讲解如何判断这两种情况,以及为什么。


相等 (最常用的情况)

这是绝大多数情况下你真正想要做的判断,判断两个字符串内容是否相同,必须使用 equals() 方法。

equals() 方法

equals() 方法是 Object 类定义的方法,String 类对其进行了重写,使其比较的是字符串的内容(字符序列)。

语法:

str1.equals(str2);

str1str2 的内容完全相同,则返回 true;否则返回 false

示例:

String s1 = new String("hello");
String s2 = new String("hello");
String s3 = "world";
相同,返回 true
System.out.println(s1.equals(s2)); // 输出: true
不同,返回 false
System.out.println(s1.equals(s3)); // 输出: false

equalsIgnoreCase() 方法

这是一个非常实用的变体,它在比较时忽略大小写

语法:

str1.equalsIgnoreCase(str2);

示例:

String s1 = "Hello";
String s2 = "hello";
String s3 = "HELLO";
System.out.println(s1.equals(s2));      // 输出: false (区分大小写)
System.out.println(s1.equalsIgnoreCase(s2)); // 输出: true (忽略大小写)
System.out.println(s1.equalsIgnoreCase(s3)); // 输出: true

判断引用相等 (较少使用)

判断两个变量是否指向内存中的同一个对象,应该使用 运算符。

比较的是两个变量在栈中存储的内存地址(引用)是否相同。

语法:

str1 == str2;

str1str2 指向同一个 String 对象,则返回 true;否则返回 false

示例:

// 情况1:通过 new 关键字创建
String s1 = new String("abc");
String s2 = new String("abc");
// s1 和 s2 是两个不同的对象,内存地址不同
System.out.println(s1 == s2); // 输出: false
// 情况2:通过字面量赋值 (Java 特有的字符串常量池机制)
String s3 = "abc";
String s4 = "abc";
// Java 会对字面量 "abc" 进行优化,只创建一个对象,s3 和 s4 都指向这个对象
System.out.println(s3 == s4); // 输出: true
// 情况3:混合情况
String s5 = "abc";
String s6 = new String("abc");
System.out.println(s5 == s6); // 输出: false,因为 s6 是 new 出来的新对象

为什么 在判断字符串内容时是危险的?

因为 比较的是内存地址,而不是内容,在开发中,我们几乎总是关心内容是否相同,而不是它们是不是同一个对象,如果你误用了 ,可能会导致逻辑错误,尤其是在处理用户输入、从文件或网络读取数据时。

反例:

// 假设这是从用户输入获取的字符串
String userInput = new Scanner(System.in).nextLine();
String password = "secret123";
// 错误的判断方式!
if (userInput == password) {
    System.out.println("密码正确!");
} else {
    System.out.println("密码错误!");
}
// 即使你输入 "secret123",这个判断也几乎永远是 false,
// 因为 userInput 是 new 出来的新对象,与 password 不是同一个引用。

最佳实践与性能考量

使用 equals() 时的 NullPointerException 风险

如果你尝试在一个 null 对象上调用 equals() 方法,程序会抛出 NullPointerException

String s1 = null;
String s2 = "hello";
// 这行代码会抛出 NullPointerException
System.out.println(s1.equals(s2)); 

解决方案:

  1. 反向调用(推荐):将常量或非 null 的对象放在 equals() 的左侧。

    // s1 是 null,表达式会变成 "hello".equals(s1),返回 false,不会报错
    System.out.println("hello".equals(s1)); 
  2. 使用 Objects.equals() (Java 7+):这是最安全、最推荐的方式。java.util.Objects 类提供了一个静态的 equals 方法,它内部已经处理了 null 的情况。

    import java.util.Objects;
    String s1 = null;
    String s2 = "hello";
    // 安全,不会抛出异常
    System.out.println(Objects.equals(s1, s2)); // 输出: false

性能:equals() vs

通常情况下, 的性能比 equals() 要快,因为 只是直接比较两个内存地址(一个原生数据类型比较),而 equals() 需要先检查类型,然后逐个字符进行比较。

性能差异只有在比较两个已知非 null 的对象时才有意义。

在编写业务代码时,可读性和正确性远比微小的性能差异重要,99% 的情况下,你应该使用 equals() 来判断字符串内容。


总结表格

方法/运算符 是否可为 null 示例 推荐场景
equals() (区分大小写) 不能null (调用方) "abc".equals(str) 判断字符串内容是否相等(默认)
equalsIgnoreCase() (忽略大小写) 不能null (调用方) "ABC".equalsIgnoreCase(str) 判断字符串内容是否相等,且不关心大小写(如用户名、密码)
Objects.equals() (区分大小写) 可以null (任一参数) Objects.equals(str1, str2) 最安全、最推荐的通用方法,能完美处理 null
内存地址 (对象引用) 可以 str1 == str2 判断两个变量是否指向同一个对象,不用于判断内容

黄金法则

当你想判断两个 String 的内容是否相同时,请使用 equals(),为了代码的健壮性,优先使用 Objects.equals(str1, str2)

分享:
扫描分享到社交APP
上一篇
下一篇