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()看 "内容"(重写后)。

相关推荐
鲸沉梦落1 小时前
JVM类加载
java·jvm
carry杰1 小时前
esayExcel导出图片
java·easyexcel 图片
路人甲ing..1 小时前
Android Studio 快速的制作一个可以在 手机上跑的app
android·java·linux·智能手机·android studio
testtraveler2 小时前
[Fix] ImportError: libtorch_cpu.so: undefined symbol: iJIT_NotifyEvent
pytorch·python·bug
心灵宝贝2 小时前
Mac 安装 JDK 8u281(JDK-8u281-1.dmg)详细步骤(附安装包)
java·macos·intellij-idea
記億揺晃着的那天2 小时前
从单体到微服务:如何拆分
java·微服务·ddd·devops·系统拆分
lang201509282 小时前
Kafka延迟操作机制深度解析
分布式·python·kafka
7ioik3 小时前
什么是线程池?线程池的作用?线程池的四种创建方法?
java·开发语言·spring
切糕师学AI3 小时前
Lombok 注解 @Slf4j
java·lombok