“==”和equals 最大的区别

简介: “==”和equals 最大的区别是“==”是运算符,如果是基本数据类型,则比较存储的值;如果是引用数据类型,则比较所指向对象的地址值。equals是Object的方法,比较的是所指向的对象的地址值,一般情况下,重写之后比较的是对象的值。

一、“==”
“==”是运算符
①如果比较的对象是基本数据类型,则比较的是其存储的值是否相等;
②如果比较的是引用数据类型,则比较的是所指向对象的地址值是否相等(是否是同一个对象)。

二、equals()
equals是Object的方法,用来比较两个对象的内容是否相等。
方法如下:

public boolean equals(Object obj) {
        return (this == obj);
    }

注意:
equals 方法不能用于比较基本数据类型,如果没有对 equals 方法进行重写,则相当于“==”,比较的是引用类型的变
量所指向的对象的地址值。

一般情况下,类会重写equals方法用来比较两个对象的内容是否相等。比如String类中的equals()是被重写了,比较的是对象的值。
三、栗子和解释说明
3.1栗子

public static void main(String[] args) {
        //基本数据类型的比较
        int num1 = 10;
        int num2 = 10;
        System.out.println(num1 == num2);   //true

        //引用数据类型的比较
        //String类(重写了equals方法)中==与equals的比较
        
        String s1 = "hello";
        String s2 = "hello";
        System.out.println(s1 == s2);    //true,比较地址值:内容相同,因为常量池中只有一个“hello”,所以它们的地址值相同
        System.out.println(s1.equals(s2));//true,比较内容:内容相同,因为常量池中只有一个“hello”,所以它们的地址值相同
        System.out.println(s1.equals("hello")); //true

       
        String s3 = new String("hello");
        String s4 = new String("hello");
        System.out.println(s3 == s4);        //false,比较地址值:s3和s4在堆内存中的地址值不同
        System.out.println(s3.equals(s4));    //true,比较内容:内容相同

        //没有重写equals方法的类中==与equals的比较 
        People p1 = new People();
        People p2 = new People();
        People p = p2;
        System.out.println(p1);//People@135fbaa4
        System.out.println(p2);//People@45ee12a7
        System.out.println(p); //People@45ee12a7
        System.out.println(p1.equals(p2));       //false,p1和p2的地址值不同
        System.out.println(p.equals(p2));        //true,p和p2的地址值相同
    }

3.2基本数据类型的比较
“==”正常比较其值。equals不用于基本数据类型的比较。

3.3引用数据类型的比较
3.3.1String类
String类对equals()方法进行了重写。

(1)创建字符串对象通常有以下两种写法:

String s1 = "hello";//在字符串常量池中创建"hello",并将地址值赋值给s1;
String s2 = new String("world");//通过new关键字在堆中创建对象,并将对象地址值赋值给s2.

对于String s2 = new String(“world”);
首先在堆内存中申请内存存储String类型的对象,将地址值赋给s2;
在方法区的常量池中找,有无hello:
若没有,则在常量池中开辟空间存储hello,并将该空间的地址值赋给堆中存储对象的空间;
若有,则直接将hello所在空间的地址值给堆中存储对象的空间。

对于String s1 = “hello”;
在方法区的常量池中找,有无hello,如果没有,就在常量池中开辟空间存储hello。
然后只需要将hello所在空间的地址值赋给 s1。

字符串作为最基础的数据类型,使用非常频繁,如果每次都通过 new 关键字进行创建,会耗费高昂的时间和空间代价。Java 虚拟机为了提高性能和减少内存开销,就设计了字符串常量池. 在JDK1.7之前字符串常量池是存储在方法区的。JDK1.7之后存储在堆中了。

(2)String类对equals的重写如下:

public boolean equals(Object anObject) {
       if (this == anObject) {
           return true;
       }
       if (anObject instanceof String) {
           String anotherString = (String)anObject;
           int n = value.length;
           if (n == anotherString.value.length) {
               char v1[] = value;
               char v2[] = anotherString.value;
               int i = 0;
               while (n-- != 0) {
                   if (v1[i] != v2[i])
                       return false;
                   i++;
               }
               return true;
           }
       }
       return false;
   }

代码解释

若当前对象和比较的对象是同一个对象,即return true。也就是Object中的equals方法。
若当前传入的对象是String类型,则比较两个字符串的长度,即value.length的长度。
若长度不相同,则return false。
若长度相同,则按照数组value中的每一位进行比较。若不同,则返回false。若每一位都相同,则返回true。
若当前传入的对象不是String类型,则直接返回false。
此外StringBuffer和StringBuilder并没有重写equals方法,其比较的还是引用类型的地址。
3.3.2未重写equals方法的类
如果类没有重写equals方法,其比较的还是引用类型的地址。

四、练手栗子
(1)下面的代码将创建几个字符串对象?2个
String s1 = new String(“Hello”);
String s2 = new String(“Hello”);

(2)在java中,String s=new String(“xyz”);创建了几个对象?A
A 1个 B 1个或2个 C 2个 D 以上都不对

(3)下面的代码输出什么?
String s1 = new String(“abc”);
String s2 = new String(“abc”);
System.out.println(s1 == s2);//false
System.out.println(s1.equals(s2)); // true

(4)下面的代码输入什么?
String s1 = “abc”;
String s2 = new String(“abc”);
s2.intern();//可以拿到s2的常量
System.out.println(s1 ==s2);//false

(5)下面的代码输出什么?

String s1= "abc";
String s2= "abc";
String s3 = new String("abc");
String s4 = new String("abc");

System.out.println("s3 == s4 : "+(s3==s4)); //false
System.out.println("s3.equals(s4) : "+(s3.equals(s4))); //true
System.out.println("s1 == s3 : "+(s1==s3)); //false
System.out.println("s1.equals(s3) : "+(s1.equals(s3))); //true
System.out.println(s1==s2); //true

(6)下面的代码输出什么?
String str1 = “ab” + “cd”;
String str11 = “abcd”;
System.out.println("str1 = str11 : "+ (str1 == str11)); //true

(7)下面的代码输出什么?
String str2 = “ab”;
String str3 = “cd”;
String str4 = str2+str3;
String str5 = “abcd”;
System.out.println("str4 = str5 : " + (str4==str5));//false!

(8)下面的代码输出什么?
final String str2 = “ab”;
final String str3 = “cd”;
String str4 = str2+str3;
String str5 = “abcd”;
System.out.println("str4 = str5 : " + (str4==str5));//true

(9)下面的代码输入什么?
String str6 = “b”;
String str7 = “a” + str6;
String str67 = “ab”;
System.out.println("str7 = str67 : "+ (str7 == str67)); //false

(10)下面的代码输入什么?
final String str8 = “b”;
String str9 = “a” + str8;
String str89 = “ab”;
System.out.println("str9 = str89 : "+ (str9 == str89)); //true

(11)下面选项结果为true的是:C

String s1="Hello";
String s2="hello";
String s3=s1.toLowerCase();
String s4=s2.toLowerCase();

A.S1==s3
B.S2==s3
C.S2==s4
D.S3==s4

相关文章
|
存储 Java 程序员
equals方法深入解析
equals方法深入解析
227 0
|
4月前
|
Java 容器
equals与hashcode的区别与联系
equals与hashcode的区别与联系
equals 和 == 的区别?
equals 和 == 的区别?
79 0
|
Java
== 和 equals 的区别是什么
== 运算符用于比较两个对象的引用是否相等。它对于基本类型比较值的相等性,对于引用类型比较引用的相等性。当使用 == 比较两个对象时,它会检查它们是否指向相同的内存地址。如果两个对象具有相同的内存地址,则它们被认为是相等的。
69 1
|
存储 Java
详解“==”和equals的区别
“==”和equals 最大的区别是 “==”是运算符,如果是基本数据类型,则比较存储的值;如果是引用数据类型,则比较所指向对象的地址值。 equals是Object的方法,比较的是所指向的对象的地址值,一般情况下,重写之后比较的是对象的值。
|
存储
==与equals方法的区别
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量的引用地址是否相等,只能用==操作符。
131 0
|
存储
"=="和 equals 方法究竟有什么区别?
"=="和 equals 方法究竟有什么区别?
126 0
|
存储 Java
细聊Equals和==的区别
Equals和==的区别可以说是在找工作的过程中笔试、面试必问必考的知识点了,今天就来说道说道!
124 0
细聊Equals和==的区别