equals比较内容是否相等,==比较是否为同一对象或基本类型值相等;基本类型用==,引用类型判内容用equals,且需防null。

初学阶段理解 equals 和双等号(==)的区别,关键不是死记“地址 vs 内容”,而是抓住它们在 Java 中的**角色定位不同、作用对象不同、底层逻辑不同**这三点。下面用贴近初学者的方式拆解:
双等号是“看是不是同一个东西”
它不关心内容长什么样,只问:这两个变量,指向的是堆里**同一个对象**吗?
- 对基本类型(如
int、char),==比较的就是数值本身,比如5 == 5是true - 对引用类型(如
String、Person),==比较的是变量里存的那个“地址编号”,就像比较两个身份证号是否完全一样 - 哪怕两个
String字符串内容一模一样,只要不是同一个对象(比如都用new String("abc")创建),==就返回false
equals 是“看长得像不像”
它是 Object 类自带的一个方法,默认行为其实和 == 一样——也是比地址。但它的设计初衷是:**留给子类自己决定什么叫“相等”**。
-
String类重写了equals,让它逐个字符比内容,所以new String("hi").equals("hi")是true -
Integer在 -128 到 127 范围内做了缓存,所以Integer a = 100; Integer b = 100;时a.equals(b)和a == b都是true;但超出范围或用new Integer(200),==就变false,而equals仍为true - 你自己写的类(比如
Student),如果不重写equals,那它就只是比地址——和==效果一样
为什么初学容易混淆?因为字符串太特殊
你一上手就用 String,但它有常量池机制,让很多现象看起来“反直觉”:
-
String s1 = "abc"; String s2 = "abc";→s1 == s2是true(因为 JVM 把相同字面量指向了同一个池中对象) -
String s3 = new String("abc"); String s4 = new String("abc");→s3 == s4是false,但s3.equals(s4)是true - 这种“有时相等、有时不等”的表现,不是
==或equals有问题,而是String的创建方式影响了内存布局
初学阶段记住这三条就够用
- 判断数字、字符这些基本类型,只用
==,不用equals(编译都通不过) - 判断两个对象“内容是否一样”,一律用
.equals(),别用==(除非你明确想检查是不是同一对象) - 调用
equals前先确保对象不为null,否则会抛NullPointerException;稳妥写法是"abc".equals(str),而不是str.equals("abc")

















