Java中的==和equals区别

本文详细解析了Java中==与equals的区别,包括它们的工作原理、如何比较基本类型与引用类型,以及String对象的特殊处理方式。此外还讨论了String对象创建的不同方式对比较结果的影响。

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

    A.==可用于基本类型和引用类型:当用于基本类型时候,是比较值是否相同;当用于引用类型的时候,是比较对象是否相同。

    B.对于String a = “a”; Integer b = 1;这种类型的特有对象创建方式,==的时候值是相同的。

    C.基本类型没有equals方法,equals只比较值(对象中的内容)是否相同(相同返回true)。

    D.一个类如果没有定义equals方法,它将默认继承Object中的equals方法,返回值与==方法相同。


详述:


    ①==和equals的实质。


    在JAVA中利用"=="比较变量时,系统使用变量在"栈"中所存的值作为比较的依据。


    基本数据类型在"栈"中存的是其内容值,而对象类型在"栈"中存的是地址,这些地址指向"堆"中的对象。


    java.lang包中的Object类有public boolean equals(Object obj)方法,它比较两个对象是否相等。


    其它对象的equals方法仅当被比较的两个引用指向的对象内容相同时,对象的equals()方法返回true。


    总之,"=="和"!="比较的是地址.也可认为"=="和"!="比较的是对象句柄;而equals()比较的是对象内容.或者说,,"=="和"!="比较的是"栈"中的内容,而equals()比较的是"堆"中的内容.


    ②==操作符。专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相当,只能用==操作符。


    Java的基本数据类型为(char,byte,short,int,long,float,double,boolean)。


    如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(对内存),变量本身也占用一块内存,例如Object obj = new Object()变量obj是一个内存,new Object()是一个内存,此时,变量所对应的内存中存储的数据就是对象占用的那块内存的首地址。对于指向对象内存的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。


    ③构造器形成的差别。对于String和Integer来说,由于他们特有的创建对象的方式。使用构造器和不使用构造器得到一个对象,==方法比较所产生的结果是不同的。 String a = “abc”; String b = "abc"; 此时a==b得到结果为true。String a = new String("abc"); String b = new String("abc");此时a==b得到的结果为false。Integer a = 1; Integer b = 1;此时a==b的结果是true。Integer a = new Integer(1); Integer b = new Integer(1);此时a==b得到的结果为false。


   通过这一点其实我们也能够更加容易理解==对内存的实际操作,实际执行的是近似于基本类型比较。


   String对象和字符串连接池:


    引号内包含文本是String类特有创建对象的方式.但是"=="返回的结果是true,为什么呢?因为在JVM内,存在字符串池,其中保存着很多 String对象,并且可以被共享使用,因此它提高了效率.字符串池由String类维护,我们可以调用intern()方法来访问字符串池。当运用引号内包含文本创建对象时,所创建的对象是加入到字符串池里面的.如果要创建下一个字符串对象,JVM首先会到字符串池中寻找,是否存在对应的字符串对象,如果存在,则返回一个己存在对象的对象的引用给要创建的对象引用.如果不存在,才会创建一个新的对象,并返回一个新对象的对象引用给要创建的对象引用.以上这段话理解起来可能比较拗口.用代码理解就是str2和str1是两个对象引用,并指向了同一个对象.所以'=='返回的是true.


    只有引号内包含文本创建对象才会将创建的对象放入到字符串池。String str = new String("abc")这种方法创建的字符串对象是不放入到字符串池的。所以,引号内包含文本创建对象的性能要比后来那种方法创建字符串对象的性能要好。


String str1 = "abc";

String str2 = "abc";


String str3 = str1+str2;   //这种创建方式是不放入字符串池的.

String str4 = str1+"cd";   //这种创建方式是不放入字符串池的.

String str5 = "ab"+str2;   //这种创建方式是不放入字符串池的.

String str6 = "ab"+"cd"; //这种创建方式是放入字符串池的.这种情况实际上是创建了1个对象,abcd"1个对象


String str7 = "abcd";


System.out.println(str1==str2); //返回ture

System.out.println(str6==str7); //返回ture


另一个问题:


我们首先来看一段 Java代码:

String str=new String("abc");  

    紧接着这段代码之后的往往是这个问题,那就是这行代码究竟创建了几个String对象呢?相信大家对这道题并不陌生,答案也是众所周知的,2个。接下来我们就从这道题展开,一起回顾一下与创建String对象相关的一些JAVA知识。

    我们可以把上面这行代码分成String str、=、"abc"和new String()四部分来看待。String str只是定义了一个名为str的String类型的变量,因此它并没有创建对象;=是对变量str进行初始化,将某个对象的引用(或者叫句柄)赋值给它,显然也没有创建对象;现在只剩下new String("abc")了。那么,new String("abc")为什么又能被看成"abc"和new String()呢?我们来看一下被我们调用了的String的构造器:

Java代码

public String(String original) {    
//other code ...    
 
    大家都知道,我们常用的创建一个类的实例(对象)的方法有以下两种:
    我们正是使用new调用了String类的上面那个构造器方法创建了一个对象,并将它的引用赋值给了str变量。同时我们注意到,被调用的构造器方法接受的参数也是一个String对象,这个对象正是"abc"。

    使用new创建对象是调用Class类的newInstance方法,利用反射机制创建对象。


   equals方法。用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。例如,对于下面的代码:


String a=new String("foo");


String b=new String("foo");


    两条new语句创建了两个对象,然后用a,b这两个变量分别指向了其中一个对象,这是两个不同的对象,他们的首地址是不同的,即a和b中存储的数值是不相同的,所以,表达式a==b即返回false,而这两个对象中内容是相同的,所以,表达式a.equals(b)将返回true。


   在实际开发中,我们经常要比较传递进行来的字符串内容是否相等,许多人稍不注意就使用==进行比较了,这是错误的,有大量这样的错误。记住,字符串的比较基本都是使用equals方法。


   ⑤如果一个类没有定义equals方法。它将继承Object类的equals方法,Object类的equals方法的实现代码如下:


boolean equals(Object o){


return this==o;


}


    这说明,如果一个类没有自己定义equals方法,它默认的equals方法(从Object类继承的)就是使用==操作符,也是比较两个变量指向的对象是否是同一个对象,这时候使用equals和使用==会得到同样的结果,如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可以认为两个对象的内容是相同的。


转载自:http://blog.sina.com.cn/s/blog_532637060100gkfc.html

<think>首先,用户的问题是:“我想理解Java中'==''equals()'的区别 请问Java中运算符==方法equals()的区别”。我需要基于提供的引用来回答这个问题。 回顾引用内容: - 引用[1]:讨论了关系运算符,包括==,但它主要关注基本数据类型的比较,如int a=1,b=2; System.out.println(a==b); //false。这显示==用于基本数据类型的值比较。 - 引用[2]:展示了三元运算符的使用,但提到了name.equals("哪吒"),这涉及到equals()方法用于字符串比较。 - 引用[3]:直接比较了Java String中的==equals()。它总结说:==比较字符串对象的地址,而equals()比较字符串的内容。还提到通过new创建的字符串,内容相同但地址不同,因此应使用equals()。 - 引用[4]:讨论了equal函数(可能是equals())==区别。它说equals()比较对象的值(包括属性),而==比较堆中的内存地址。还提到在重写equals()时,需要检查是否为同一对象。 用户的问题是关于==equals()的区别,所以我需要整合这些信息。 关键点: - == 运算符:在Java中,==用于基本数据类型(如int, char)时比较值;对于对象引用时比较内存地址(即是否指向同一个对象)。 - equals() 方法:这是Object类的一个方法,默认实现是使用==比较内存地址。但许多类(如String)重写了equals()来比较内容或值。 根据引用[3][4],对于字符串,==比较地址,equals()比较内容。引用[4]还强调,equals()可以比较对象的属性值,如果被重写。 我的回答需要: - 使用中文,因为系统指令说“使用中文回答”。 - 结构清晰,逐步解释。 - 包括行内数学表达式用$...$,但在这个上下文中,可能不需要数学表达式,除非有相关计算。用户问题不涉及数学,所以可能不需要。 - 独立公式用$$...$$,但同样,这里可能不适用。 - 生成相关问题:在回答末尾添加相关问题。 - 在引用的段落末尾添加引用标识,如[^1]。 系统指令说:“回答中引用的段落末尾自然地添加引用标识”。所以,当我引用信息时,需要添加引用。 参考的引用是[^1]到[^4],所以我应该使用这些来支持我的回答。 回答结构: 1. 介绍:简述==equals()的基本区别。 2. 详细解释==运算符:用于基本类型对象引用。 3. 详细解释equals()方法:默认行为重写情况。 4. 示例:使用提供的引用中的例子或创建新例子。 5. 总结区别。 6. 添加相关问题。 确保回答真实可靠,基于提供的引用。 逐步构建回答: - 开头:直接回答用户问题。 - 解释==:当用于基本数据类型时,比较值;当用于对象时,比较内存地址。引用[1][3]支持。 - 解释equals():默认比较内存地址(与==相同),但许多类如String重写它以比较内容。引用[3][4]支持。 - 示例:使用字符串例子,如引用[3]中的:new String("hello") == new String("hello") 为false,但equals()为true。 - 注意事项:引用[4]提到重写equals()时需要考虑对象一致性。 - 相关问题:生成3-4个相关问题。 相关问题想法: 1. 如何重写equals()方法? 2. 在哪些场景下应该使用==而不是equals()? 3. equals()hashCode()的关系是什么? 4. 对于基本数据类型包装类(如Integer),==equals()的行为如何? 最后,添加引用标识。</think>### Java中'==''equals()'的区别Java中,运算符`==`方法`equals()`都用于比较操作,但它们的用途行为有本质区别。理解这些区别对于避免常见编程错误(如字符串或对象比较不准确)至关重要。下面我将逐步解释两者的差异,并结合示例说明。 #### 1. **`==`运算符的基本行为** - **作用**:`==`是Java中的关系运算符,用于比较两个操作数的“值”。但具体行为取决于操作数的类型: - **对于基本数据类型**(如`int`, `char`, `double`等),`==`直接比较变量的值是否相等。例如: ```java int a = 1; int b = 2; System.out.println(a == b); // 输出 false,因为值不相等 [^1] ``` - **对于对象引用**(如`String`, 自定义类等),`==`比较的是内存地址(即对象在堆中的引用地址)。如果两个引用指向同一个对象实例,则返回`true`;否则返回`false`,无论对象内容是否相同。例如: ```java String s1 = "哪吒"; String s2 = new String("哪吒"); // 通过new创建新对象 System.out.println(s1 == s2); // 输出 false,因为s1s2是不同的对象引用 [^3] ``` - **关键点**:`==`不关心对象的内容,只关心引用是否指向同一块内存。 #### 2. **`equals()`方法的基本行为** - **作用**:`equals()`是`Object`类中定义的方法(所有Java类都继承自`Object`),默认实现是比较对象的内存地址(即与`==`行为相同)。但许多内置类(如`String`)重写了`equals()`方法,使其比较对象的“内容”或“值”: - **默认行为**:如果不重写,`equals()`等价于`==`,比较内存地址。 - **重写后的行为**:对于`String`、`Integer`等类,`equals()`被重写为比较对象的内容是否相等。例如: ```java String name1 = "哪吒"; String name2 = new String("哪吒"); System.out.println(name1.equals(name2)); // 输出 true,因为内容相同 [^3] ``` - 对于自定义类,开发者可以重写`equals()`来定义“相等性”标准(如比较属性值)。引用[4]指出:重写时需先检查是否为同一对象(`==`),然后比较属性值;如果所有属性相等,则返回`true`,否则`false` [^4]。 - **关键点**:`equals()`专注于逻辑相等性,而非物理地址。它更适合比较对象的内容。 #### 3. **核心区别总结** - **比较维度**: - `==`:比较值(基本类型)或内存地址(引用类型)。 - `equals()`:比较内容或自定义逻辑(如果重写)。 - **适用场景**: - 使用`==`当需要检查基本数据类型的值相等或对象引用是否相同(如单例模式)。 - 使用`equals()`当需要比较对象的内容(如字符串、集合元素)。 - **常见误区**:在字符串比较中,误用`==`可能导致错误。例如: ```java String str1 = "hello"; String str2 = new String("hello"); System.out.println(str1 == str2); // false(地址不同) System.out.println(str1.equals(str2)); // true(内容相同) [^3] ``` #### 4. **示例代码演示** 以下代码综合展示`==``equals()`的行为: ```java public class ComparisonDemo { public static void main(String[] args) { // 基本数据类型比较 int x = 5; int y = 5; System.out.println(x == y); // true(值相等) [^1] // 对象引用比较 String obj1 = new String("Java"); String obj2 = new String("Java"); System.out.println(obj1 == obj2); // false(不同地址) [^3] System.out.println(obj1.equals(obj2)); // true(内容相同) [^3] // 三元运算符结合equals()的实用示例 String name = "哪吒"; boolean ret = name.equals("哪吒") ? true : false; // 简化比较 System.out.println(name + (ret ? "很强" : "很弱")); // 输出 "哪吒很强" [^2] } } ``` #### 5. **注意事项** - 重写`equals()`时,必须同时重写`hashCode()`方法,以保持一致性(例如在`HashMap`中使用)[^4]。 - 对于基本数据类型的包装类(如`Integer`),`==`可能因缓存机制(如`-128`到`127`)而表现不同,但`equals()`总是比较值。 - 在条件判断中,优先使用`equals()`避免空指针异常(如`"text".equals(variable)`而非`variable.equals("text")`)。 通过以上分析,您可以看到`==``equals()`在比较机制上的根本差异:`==`关注地址或值,`equals()`关注逻辑内容。正确选择能提升代码健壮性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值