==是运算符,比较基本类型值或引用类型地址;equals()是Object方法,重写后比较内容。基本类型只能用==;引用类型用==比较内存地址,equals()默认比地址但常用类已重写为比内容;包装类在[-128,127]内缓存导致==偶发true,应始终用equals()判逻辑相等。
在Java中,==和equals()根本不是同一类操作:一个是运算符,一个是继承自Object的方法;它们的比较目标不同,适用场景也完全不同。
int、char、boolean 等 8 种基本数据类型不是对象,没有方法,因此不能写 5.equals(5)——这会直接编译失败。它们之间只能用 == 比较值:
int a = 100; int b = 100; System.out.println(a == b); // truedouble x = 0.1 + 0.2; double y = 0.3; System.out.println(x == y); // false(浮点精度问题)String、Integer、ArrayList 或自定义类的对象,都是引用类型。== 判断的是两个变量是否指向堆中同一块内存:
String s1 = new String("hi"); String s2 = new String("hi"); System.out.println(s1 == s2); // false(两个独立对象)String s3 = "ok"; String s4 = "ok"; System.out.println(s3 == s4); // true
(字符串常量池复用)User u1 = new User("A", 25); User u2 = u1; System.out.println(u1 == u2); // true(同一引用)equals() 是 Object 的方法,原始实现就是 return (this == obj);,和 == 效果一样。但很多 JDK 类重写了它:
"abc".equals("abc") // true(逐字符比内容)new Integer(100).equals(100) // true(自动拆箱后比 int 值)Arrays.asList(1,2).equals(Arrays.asList(1,2)) // true(按元素顺序和值比)equals(),默认仍比地址;若需按字段逻辑判断相等(比如 id 和 name 都相同即视为相同用户),必须手动重写,并建议同步重写 hashCode()。Integer、Byte、Character 在 [-128, 127] 范围内会缓存对象:
Integer a = 100; Integer b = 100; System.out.println(a == b); // true(JVM 缓存)Integer c = 200; Integer d = 200; System.out.println(c == d); // false(各自 new)c.equals(d) 始终是 true,因为 Integer.equals() 比的是 int 值。== 判断包装类的逻辑相等。