首页 / 资讯中心 / 文章详情

Java基础:为什么两个String明明一样,使用==比较却是false?深入理解==和equals()区别

Java基础:为什么两个String明明一样,使用==比较却是false?深入理解==和equals()区别 ★ FEATURED ARTICLE
在学习 Java 的过程中和equals()几乎是每个初学者都会遇到的一个问题。很多刚开始学习 Java 的同学都会记住一句话String 比较不要使用 应该使用 equals()但是为什么为什么下面这段代码中两个 String 明明都是hello使用比较结果却是falsepublic class Main { public static void main(String[] args) { String s1 hello; String s2 new String(hello); System.out.println(s1 s2); System.out.println(s1.equals(s2)); } }运行结果false true这篇文章就来详细分析 Java 中和equals()的区别。一、Java中的到底比较什么在 Java 中的作用根据数据类型不同有所区别。1. 基本数据类型使用比较值例如public class Main { public static void main(String[] args) { int a 10; int b 10; System.out.println(a b); } }输出true因为对于基本数据类型intdoublefloatcharboolean比较的是变量中存储的具体值。2. 引用类型使用比较地址String 属于引用类型。例如String s1 new String(hello); String s2 new String(hello);这两个对象虽然内容一样hello但是它们实际上创建了两个不同的对象。可以理解为s1 --- String对象1(hello) s2 --- String对象2(hello)所以System.out.println(s1 s2);比较的是s1 和 s2 是否指向同一个对象答案是false因此对于引用类型 比较的是对象地址更准确地说是两个引用是否指向同一个对象二、equals()比较的是什么equals()是 Object 类中的方法。Java 中所有类默认都继承 Object。Object 类中的 equals 方法默认比较的是对象地址。源码大致如下public boolean equals(Object obj) { return this obj; }也就是说如果一个类没有重写 equals()那么它和 的效果基本一样。但是 String 重写了 equals() 方法。String 中的 equals() 比较的是两个字符串对象的内容是否相同例如String s1 new String(hello); String s2 new String(hello); System.out.println(s1.equals(s2));结果true虽然s1 s2是false但是s1.equals(s2)是true因为两个字符串的内容都是hello三、String常量池为什么会导致有时候是true很多同学看到下面代码会更加疑惑String a hello; String b hello; System.out.println(a b);结果true为什么不是说 String 使用 比较地址吗这里涉及 Java 的字符串常量池。什么是字符串常量池Java 为了提高字符串的复用效率设计了字符串常量池。当我们直接创建字符串String a hello;JVM 会先检查字符串常量池中是否已经存在hello。如果存在直接复用。如果不存在创建新的字符串对象并放入常量池。所以String a hello; String b hello;实际上可能是a \ --- hello b /两个引用指向同一个字符串对象。因此a b结果true四、为什么new String()会让变成false继续看String a hello; String b new String(hello); System.out.println(a b);结果false原因是new String()会强制创建一个新的对象。内存中类似字符串常量池 hello 堆 String对象 | --- hello虽然两个字符串内容一样但是对象不同。所以a b结果false五、String比较时为什么推荐使用equals()因为我们开发过程中大部分情况下想比较的是两个字符串的内容是否一样例如登录判断String username admin; if (username.equals(admin)) { System.out.println(登录成功); }我们关注的是username里面存储的文字是不是admin而不是username和admin是不是同一个对象。所以应该使用equals()六、equals()使用时还需要注意空指针问题下面代码String username null; System.out.println(username.equals(admin));运行会出现NullPointerException原因username本身是null没有对象可以调用equals()方法。更安全的写法System.out.println(admin.equals(username));因为admin一定不是null。即使username null;结果也只是false不会出现异常。实际开发中经常看到if (admin.equals(username)) { }就是为了避免空指针异常。七、Objects.equals()更加安全Java还提供了Objects.equals()用于安全比较两个对象。例如String a null; String b hello; System.out.println(Objects.equals(a, b));结果false它内部会帮助我们处理 null 情况。常用于Objects.equals(user.getName(), 张三)这种场景。八、和equals()区别总结比较方式比较内容基本数据类型 比较值引用类型 比较是否同一个对象Object.equals()默认比较地址String.equals()比较字符串内容简单记忆 问 是不是同一个对象 equals() 问 内容是不是一样九、实际开发中应该怎么选择如果比较 String推荐str1.equals(str2)或者更安全Objects.equals(str1, str2)不要写str1 str2因为你无法保证两个字符串一定来自同一个对象。总结刚开始学习 Java 的时候我一直把String比较用equals()当成一个需要背下来的规则。但是深入理解之后会发现它背后的原因其实很简单关注的是对象关系equals()关注的是内容关系所以以后遇到字符串比较问题不要先想“这个题是不是要求用 equals”而应该先问我现在想比较的是两个对象还是两个对象里面的数据理解这一点和equals()就不会再混淆了。如果你也是刚开始学习 Java建议把这些基础知识点真正弄懂。
阅读完成 · 觉得有帮助?
咨询建站