java学习--==和equals

在 Java 中,==equals() 是用于比较对象 / 值的两种核心方式,但本质和适用场景截然不同,以下从底层原理、使用场景、典型示例三方面详细解析:

一、==:比较的是 "值" 或 "内存地址"

==运算符,其比较规则取决于操作数的类型:

1. 基本数据类型(byte/short/int/long/float/double/char/boolean)

直接比较值是否相等(无需关注内存地址)。

示例:

复制代码
int a = 10;
int b = 10;
System.out.println(a == b); // true(值相等)

char c1 = 'A';
char c2 = 65; // 'A'的ASCII码是65
System.out.println(c1 == c2); // true(值相等)
2. 引用数据类型(类 / 接口 / 数组 / String 等)

比较对象的内存地址是否相同(即是否为同一个对象)。

示例:

复制代码
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false(两个不同对象,地址不同)

String s3 = "hello";
String s4 = "hello";
System.out.println(s3 == s4); // true(字符串常量池复用,地址相同)

User u1 = new User("张三");
User u2 = u1; // u2指向u1的地址
System.out.println(u1 == u2); // true(同一对象)

二、equals():比较的是 "对象的内容是否相等"

equals()Object 类的方法 ,默认实现等价于==(比较地址),但可被子类重写以实现 "内容比较"。

1. Object 类的默认实现
复制代码
public boolean equals(Object obj) {
    return (this == obj); // 本质是==,比较地址
}
2. 子类重写equals()的典型场景
  • String 类:重写后比较字符串的字符序列是否相同。

  • 示例:

    复制代码
    String s1 = new String("hello");
    String s2 = new String("hello");
    System.out.println(s1.equals(s2)); // true(内容相同)
  • 包装类(Integer/Boolean 等):重写后比较数值是否相同。

  • 示例:

    复制代码
    Integer i1 = new Integer(100);
    Integer i2 = new Integer(100);
    System.out.println(i1.equals(i2)); // true(数值相同)
  • 自定义类 :需手动重写equals()以比较对象属性。示例(User 类重写equals()):

    复制代码
    class User {
        private String name;
        private int age;
    
        // 构造方法、getter/setter省略
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true; // 地址相同直接返回true
            if (o == null || getClass() != o.getClass()) return false; // 类型不同返回false
            User user = (User) o;
            return age == user.age && Objects.equals(name, user.name); // 比较属性
        }
    }
    
    // 使用
    User u1 = new User("张三", 20);
    User u2 = new User("张三", 20);
    System.out.println(u1.equals(u2)); // true(属性相同)

三、== vs equals() 核心区别表

特性 == equals()
本质 运算符 Object 类的方法(可重写)
基本类型比较 比较值 不适用(基本类型无equals()
引用类型比较 比较内存地址(是否同一对象) 默认比较地址,重写后比较内容
适用场景 基本类型值比较、引用地址比较 引用类型内容比较

四、常见坑点与注意事项

  1. String 的==陷阱

    • 字符串字面量("hello")会存入常量池 ,相同字面量复用地址,==返回 true;
    • new String("hello")会创建新对象(堆内存),即使内容相同,==返回 false。
  2. 包装类的缓存机制

    • Integer 对-128~127的数值缓存,Integer i1=100; Integer i2=100;==返回 true;超出范围则返回 false(需用equals())。
  3. 自定义类未重写equals() :直接使用equals()等价于==,需手动重写(结合Objects.equals()避免空指针)。

  4. null 值比较

    • ==可直接比较 null(如obj == null);

    • equals()调用前需判空(否则空对象调用会抛NullPointerException):

      复制代码
      String s = null;
      System.out.println(s.equals("hello")); // 报错NullPointerException
      System.out.println("hello".equals(s)); // false(安全写法)

五、总结

  • 基本类型比较 :用==
  • 引用类型内容比较 :用equals()(确保子类已重写);
  • 引用地址比较 :用==
  • 字符串比较 :优先用equals(),避免==的常量池陷阱。

记住核心逻辑:==看 "地址 / 值",equals()看 "内容"(重写后)。

相关推荐
linuxxx1103 分钟前
python变量引用的小案例
python
你曾经是少年7 分钟前
Java 关键字
java
海南java第二人10 分钟前
SpringBoot启动流程深度解析:从入口到容器就绪的完整机制
java·开发语言
问今域中12 分钟前
Spring Boot 请求参数绑定注解
java·spring boot·后端
星火开发设计14 分钟前
C++ queue 全面解析与实战指南
java·开发语言·数据结构·c++·学习·知识·队列
rgeshfgreh16 分钟前
Java+GeoTools+PostGIS高效求解对跖点
java
鱼跃鹰飞17 分钟前
DDD中的防腐层
java·设计模式·架构
计算机程序设计小李同学19 分钟前
婚纱摄影集成管理系统小程序
java·vue.js·spring boot·后端·微信小程序·小程序
2501_9361460421 分钟前
烟草叶片病害检测_YOLO11-C3k2-MSBlock模型详解
python
Data_agent33 分钟前
Python 编程实战:函数与模块化编程及内置模块探索
开发语言·python