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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值