==和equals的区别 null和""的区别

本文详细解析了Java中==操作符与equals方法的区别,包括它们的用途、工作原理及如何正确使用。并通过实例展示了字符串比较时两者的不同表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 java中的数据类型,可分为两类: 
1.基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean 
  他们之间的比较,应用双等号(==),比较的是他们的值。 
2.复合数据类型(类) 
  当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但 在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
  对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。
 1 public class TestString {
 2  public static void main(String[] args) {
 3 String s1 = "Monday";
 4 String s2 = "Monday";
 5 if (s1 == s2)
 6 {
 7 System.out.println("s1 == s2");}
 8 else{
 9 System.out.println("s1 != s2");}
10 }
11 }
编译并运行程序,输出:s1 == s2说明:s1 与 s2 引用同一个 String 对象 -- "Monday"!
2.再稍微改动一下程序,会有更奇怪的发现:
public class TestString {
public static void main(String[] args) {
String s1 = "Monday";
String s2 = new String("Monday");
if (s1 == s2)
{System.out.println("s1 == s2");}
else
{System.out.println("s1 != s2");}
if (s1.equals(s2)) {System.out.println("s1 equals s2");}
else{
System.out.println("s1 not equals s2");}
}
}
我们将s2用new操作符创建
程序输出:
s1 != s2
s1 equals s2
说明:s1 s2分别引用了两个"Monday"String对象


3. 字符串缓冲池
原来,程序在运行的时候会创建一个字符串缓冲池当使用 s2 = "Monday" 这样的表达是创建字符串的时候,程序首先会在这个String缓冲池中寻找相同值的对象,在第一个程序中,s1先被放到了池中,所以在s2被创建的时候,程序找到了具有相同值的 s1
将s2引用s1所引用的对象"Monday"
第二段程序中,使用了 new 操作符,他明白的告诉程序:"我要一个新的!不要旧的!"于是一个新的"Monday"Sting对象被创建在内存中。他们的值相同,但是位置不同,一个在池中游泳一个在岸边休息。哎呀,真是资源浪费,明明是一样的非要分开做什么呢?

4.再次更改程序:
public class TestString {
public static void main(String[] args) {
String s1 = "Monday";
String s2 = new String("Monday");
s2 = s2.intern();
if (s1 == s2)
{System.out.println("s1 == s2");}
else
{System.out.println("s1 != s2");}
if (s1.equals(s2)) {System.out.println("s1 equals s2");}
else{
System.out.println("s1 not equals s2");}
}
}
 
这次加入:s2 = s2.intern();
程序输出:
s1 == s2
s1 equals s2

原 来,(java.lang.String的intern()方法"abc".intern()方法的返回值还是字符串"abc",表面上看起来好像这个方 法没什么用处。但实际上,它做了个小动作:检查字符串池里是否存在"abc"这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会 把"abc"添加到字符串池中,然后再返回它的引用。



null和“”的区别

String str1 = null; str引用为空
String str2 = ""; str引用一个空串


也就是null没有分配空间,""分配了空间,因此str1还不是一个实例化的对象,而str2已经实例化。
注意因为null不是对象,""是对象。所以比较的时候必须是 if(str1==null){...}和if(str2.equals("")){...}。
对象用equals比较,null用等号比较。因此,如果str1=null;下面的写法错误: 
if(str1.equals("")||str1==null){//如果str1没有值,则.... 
//。。。。 

正确的写法是 if(str1==null||str1.equals("")){ //先判断是不是对象,如果是,再判断是不是空字符串 
//... 
}
打个比方:一个空玻璃杯,你不能说它里面什么都没有,因为里面有空气,当然也可以把它弄成真空,null与" "的区别就象真空与空气一样。




下面关于一篇比较好的见解:地址http://www.hui52.com/archives/165.html

equals()和“==”操作用于对象的比较,检查俩对象的相等性,但是他们俩的主要区别在于前者是方法后者是操作符。由于java不支持操作符重载(overloading),“==”的行为对于每个对象来说与equals()是完全相同的,但是equals()可以基于业务规则的不同而重写(overridden )。另一个需要注意的不同点是“==”习惯用于原生(primitive)类型之间的比较,而equals()仅用于对象之间的比较。同时初学者奋力地想找到什么时候使用等号操作“==”,什么时候使用equals方法。这篇教程中你将将看到equals()方法和“==”操作是如果工作的、他们之间有什么不同、什么时候用“==”、什么时候使用equals()方法。
“==”等号操作是什么
“==”或等号操作在Java编程语言中是一个二元操作符,用于比较原生类型和对象。就原生类型如boolean、int、float来说,使用“==”来比较两者能够很好的工作,但是在比较对象的时候,就会与equals()造成困惑,“==”对比两个对象基于内存引用,所以“==”操作将返回true如果两个对象的引用完全相同(指向同一个对象)时,否则返回false。


什么是equals方法
equals()方法定义在Object类里面,根据具体的业务逻辑来定义该方法,用于检查两个对象的相等性。例如:两个Employees被认为是相等的如果他们有相同的empId的话,你可以在你自己的domain对象中重写equals方法用于比较哪两个对象相等。equals与hashcode是有契约的(无论什么时候你重写了equals方法,你同样要重写hashcode()方法),默认的equals方法实现是与“==”操作一样的,基于业务需求重写equals方法是最好的实践之一,同样equals与compareTo保持一致也不足为奇,以至于存储对象在Treemap或treeset集合中时,将使用compareTo方法检查相等性,行为是一致的。

==与equals方法的区别
==与equals的主要区别是:==常用于比较原生类型,而equals()方法用于检查对象的相等性。另一个不同的点是:如果==和equals()用于比较对象,==返回true当且两个引用地址相同,而equals()可以返回true或者false主要取决于重写实现。最常见的一个例子,字符串的比较,不同情况==和equals()返回不同的结果。

字符串的==和equals对比
字符串的比较是一个常见的情景,因为java.lang.String类重写了equals方法,它返回true如果两个字符串对象包含有相同的内容,但是==只有他们的引用地址相同时才返回true,下面这个例子就是通过==和equals方法分别比较两个字符串。

String personalLoan = new String("cheap personal loans");
String homeLoan = new String("cheap personal loans");
//since two strings are different object result should be false
boolean result = personalLoan == homeLoan;
System.out.println("Comparing two strings with == operator: " + result);
//since strings contains same content , equals() should return true
result = personalLoan.equals(homeLoan);
System.out.println("Comparing two Strings with same content using equals method: " + result);
homeLoan = personalLoan;
//since both homeLoan and personalLoand reference variable are pointing to same object
//"==" should return true
result = (personalLoan == homeLoan);
System.out.println("Comparing two reference pointing to same String with == operator: " + result);
Output:
Comparing two strings with == operator: false
Comparing two Strings with same content using equals method: true
Comparing two reference pointing to same String with == operator: true

==与equals在对象之间的对比
另一中情景是:当你对比两个对象时在选择==和equals方法中很容易困惑,当你比较的两个引用指向的对象是Object的类型的时候,那么你看到的结果和==是一致的,因为默认的equals方法实现仅仅比较的内存地址。如果两个引用变量完全指向的是同一个对象的话就返回true,下面这个例子是equals和==方法操作比较的是两个对象。
Object obj1 = new Object();
Object obj2 = new Object();
// == should return false
result = (obj1==obj2);
System.out.println("Comparing two different Objects with == operator: " + result);
//equals should return false because obj1 and obj2 are different
result = obj1.equals(obj2);
System.out.println("Comparing two different Objects with equals() method: " + result);
// "==" should return true because both obj1 and obj2 points same object
obj1=obj2;
result = (obj1==obj2);
System.out.println("Comparing two reference pointing to same Object with == operator: " + result);
Output:
Comparing two different Objects with == operator: false
Comparing two different Objects with equals() method: false
Comparing two reference pointing to same Object with == operator: true
总结:
使用==比较原生类型如:boolean、int、char等等,使用equals()比较对象。
==返回true如果两个引用指向相同的对象,equals()的返回结果依赖于具体业务实现
字符串的对比使用equals()代替==操作符
以上就是关于equals方法和==操作符的区别,其主要的不同是一个是操作符一个是方法,==用于对比原生类型而equals()方法比较对象的相等性。

<think>嗯,用户问的是“==equals的关系区别。这个问题在Java里挺常见的,可能用户刚开始学编程,或者在面试准备中遇到了这个问题。我需要先回忆一下这两个操作符的基本概念,然后整理它们的区别适用场景。 首先,“==”是操作符,而equals是方法。这应该是它们的根本区别。那具体来说,“==”比较的是对象的引用是否指向同一内存地址,也就是是否同一个对象。而equals方法通常是用来比较对象的内容是否相等,但这也取决于类如何重写这个方法。比如,String类重写了equals,所以比较的是字符串内容,而如果自己创建的类没有重写equals,那么默认还是使用Object类的equals,这时候==”一样,比较的是引用。 然后,可能需要举例子来说明。比如两个String对象,用new创建的,虽然内容相同,但“==”比较的是地址,所以返回false,而equals比较内容,返回true。但如果是字面量创建的字符串,Java可能会优化,让它们指向同一个对象,这时候“==”可能返回true。这可能需要注意。 接下来,基本数据类型包装类的情况。比如intInteger,当使用“==”比较时,如果Integer对象在缓存范围内(-128到127),可能会返回true,超出的话就是false,这时候应该用equals来比较值。比如Integer a = 100Integer b=100,a==b是true,但如果是200,a==b就是false,这时候需要用equals。 还要注意null的情况。如果一个对象为null,调用equals会抛出NullPointerException,所以在使用前需要检查是否为null。而“==”比较null的时候不会有问题,比如obj == null这样的判断是安全的。 另外,覆盖equals方法时通常也要覆盖hashCode方法,这是Java中的约定,特别是当对象用在散列表中的时候。不过用户的问题可能不涉及这部分,但如果有更深入的问题可能需要提到。 总结的话,应该分点说明区别,包括比较的内容、适用场景、例子等。结构上可能需要先解释各自的定义,再对比,然后举例子,最后总结使用场景。用户可能需要具体的代码示例来理解,所以例子很重要。 需要确保语言准确,比如“==”比较的是对象的内存地址,而equals比较内容,但要注意默认情况下的equals行为。可能用户会混淆这两个,特别是在处理字符串的时候,常见的陷阱就是用了“==”而不是equals,导致意外的结果。 另外,可能用户想知道什么时候用哪个,所以给出使用建议:基本数据类型用“==”,对象比较内容用equals,但要确保该类正确重写了equals方法。如果是自定义对象,需要自己重写equals来实现内容的比较。 最后检查是否有遗漏点,比如基本类型引用类型在使用“==”时的不同,或者自动装箱带来的影响。例如,两个Integer对象使用“==”比较,如果值相同但在缓存范围外,会返回false,这时候应该用equals。</think>### "==" equals 的关系与区别详解 #### 一、核心区别 1. **本质不同** - **`==`**:是运算符,用于**比较对象的引用(内存地址)**或基本数据类型的值。 - **`equals()`**:是方法,用于**比较对象的内容是否逻辑相等**(需依赖具体类的实现)。 2. **行为对比表** | 场景 | == 的行为 | equals 的默认行为 | equals 的重写行为(如 String) | |----------------|--------------------------|--------------------------|--------------------------------| | 基本数据类型 | 比较值是否相等 | 不适用 | 不适用 | | 对象引用 | 比较内存地址是否相同 | 比较内存地址是否相同 | 比较对象内容是否相等 | --- #### 二、深入分析 1. **基本数据类型比较** ```java int a = 5; int b = 5; System.out.println(a == b); // true(比较值) ``` 2. **对象引用比较(未重写 equals)** ```java Object obj1 = new Object(); Object obj2 = new Object(); System.out.println(obj1 == obj2); // false(不同内存地址) System.out.println(obj1.equals(obj2)); // false(Object 默认用 == 实现) ``` 3. **String 的特殊性** ```java String s1 = new String("hello"); String s2 = new String("hello"); System.out.println(s1 == s2); // false(不同对象) System.out.println(s1.equals(s2)); // true(String 重写 equals 比较内容) ``` 4. **自动装箱陷阱(Integer 缓存)** ```java Integer i1 = 127; Integer i2 = 127; System.out.println(i1 == i2); // true(-128~127 缓存范围内) Integer i3 = 200; Integer i4 = 200; System.out.println(i3 == i4); // false(超出缓存范围) System.out.println(i3.equals(i4)); // true(比较值) ``` --- #### 三、关键规则总结 1. **`==` 使用场景** - 比较基本数据类型的值 - 检查对象是否为同一实例 - 判断引用是否为 `null` 2. **`equals()` 使用场景** - 需要逻辑相等性判断时(如字符串内容、自定义业务规则) - 注意必须重写 `hashCode()` 以保持一致性(HashMap/HashSet 依赖此规则) --- #### 四、自定义类示例 ```java class Person { String name; @Override public boolean equals(Object o) { if (this == o) return true; // 优化:同一对象直接返回 true if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return Objects.equals(name, person.name); // 实际内容比较 } } ``` --- #### 五、常见误区 1. **混淆字符串字面量与对象** ```java String a = "text"; // 可能指向字符串常量池同一对象 String b = new String("text"); System.out.println(a == b); // false ``` 2. **未处理 null 导致的 NPE** ```java String str = null; System.out.println(str.equals("test")); // 抛出 NullPointerException System.out.println("test".equals(str)); // 安全写法(推荐) ``` --- #### 六、最佳实践 1. 对象内容比较时,优先使用重写后的 `equals()` 2. 对可能为 `null` 的对象,采用逆向调用方式:`"常量".equals(变量)` 3. 自定义类必须同时重写 `equals()` `hashCode()`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野火少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值