Java中==和 equals 的区别

本文详细解释了Java中`==`和`equals()`的区别,尤其是在对象和基本数据类型的比较上。重点讲解了引用类型如何通过内存地址进行比较,以及String类的特殊equals()行为和intern机制。此外,还强调了在自定义类中正确使用equals()和hashCode()的重要性。

作用

==

它的作⽤是判断两个对象的地址是不是相等。即,判断两个对象是不是同⼀个对象(基本数据类型 == 比较的是值,引⽤数据类型 == 比较的是内存地址)。

equals()

它的作⽤也是判断两个对象是否相等。但是这个“相等”一般也分两种情况:

  • 默认情况:类没有覆盖 equals() ⽅法。则通过 equals() 比较该类的两个对象时,等价于通过“ == ”比较这两个对象,还是相当于比较内存地址。
  • 自定义情况:类覆盖了 equals() ⽅法。我们平时覆盖的 equals()方法一般是比较两个对象的内容是否相同,自定义了一个相等的标准,也就是两个对象的值是否相等。

举例

1. 对于基本数据类型:

  • 使用 == 操作符来比较两个基本类型(如 int、char、boolean 等)的变量时,它会直接比较它们存储的值是否相等。

例如:

int x = 10;
int y = 10;
System.out.println(x == y); // 输出:true

2. 对于引用类型(如对象):

  • 当使用 == 操作符比较两个引用类型的变量时,它检查的是两个引用是否指向内存中的同一个对象。也就是说,它比较的是对象的内存地址。

例如:

String s1 = new String("Hello");
String s2 = new String("Hello");
System.out.println(s1 == s2); // 输出:false,因为s1和s2指向了堆中两个不同的对象,尽管内容相同

String s3 = s1;
System.out.println(s1 == s3); // 输出:true,因为s1和s3指向同一对象

String特殊的==

在特定的情况下,编译器会对字面量字符串进行优化(intern机制),如果字符串字面值一样,那么它们会指向内存中的同一个常量池地址

隐式使用字面量创建字符串

在编译期或运行期,当你直接使用双引号创建字符串(即字面量形式)时,JVM会自动执行intern操作,将这些字符串放入常量池中

private   String p1 = "1";
private   String p2 = "1";
System.out.println(p1 == p2);// 输出:true,因为p1,p2 指向内存中的同一个常量池地址
显式调用intern()方法

在代码中对一个String对象调用str.intern()时,如果常量池中已有该字符串,则返回常量池中的引用;否则,将此字符串添加到常量池,并返回常量池中的新引用

String s1 = new String("Hello");
s1 = s1.intern();
String s2 = "Hello";
System.out.println(s1 == s2); // 输出true,因为s1通过intern()后和s2指向了常量池中的同一个"Hello"
Spring Boot中Request的String

在Spring Boot框架处理HTTP请求时,会将请求参数解析为字符串对象,但这个过程并不会涉及intern机制的使用

POST http://localhost:8080/stringTest
Content-Type: application/json

{
  "name": "jk"
}
private String name = "jk";
@PostMapping("stringTest")
public void test(@RequestBody StringTest req) throws LoginException {
    System.out.println(name == req.getName());//输出false
}
private String name = "jk";
@PostMapping("stringTest")
public void test(@RequestBody StringTest req) throws LoginException {
    req.setName(req.getName().intern());
    System.out.println(name == req.getName());//输出true,因为name,req.getName() 指向内存中的同一个常量池地址
}

3. 对于Object类及其子类:

  • equals() 方法默认的行为与 == 类似,即比较对象的引用是否相等。然而,大多数Java类库中的类(尤其是集合框架中的类,如String、Integer等)都重写了 equals() 方法,使其基于对象的内容而不是引用进行比较。

例如:

String s4 = new String("World");
String s5 = new String("World");
System.out.println(s4.equals(s5)); // 输出:true,因为String类重写了equals方法,基于字符串内容进行比较

因此,在处理对象时,如果你需要根据对象的内在状态或属性来判断它们是否相等,通常应该使用 equals() 方法,并且确保在自定义类中正确地覆盖并实现 equals()hashCode() 方法,以保持一致性并符合Java约定。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值