成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java中的equals()與==的區別與用法

人工智能
new String("hello") 在執行的時候,會先在字符串常量池中創建對象,然后再在堆中創建對象;執行 intern() 方法的時候發現字符串常量池中已經有了‘hello’這個對象,所以就直接返回字符串常量池中的對象引用了,那再與字符串常量池中的‘hello’比較,所以結果是true。

在Java開發中有有一個看似簡單,但是在網上有大量關于話題和問題,就是equals() 和 == 操作符有什么區別

  • ==: 操作符用于比較兩個對象的地址是否相等
  • equals(): 方法用于比較兩個對象的內容是否相等

今日內容介紹,大約花費9分鐘

圖片圖片

為了更好地理解這個區別,讓我們看一個例子:

String str1 = new String("Hello");
String str2 = new String("Hello");

System.out.println(str1.equals(str2)); // 輸出 true
System.out.println(str1 == str2); // 輸出 false

例子中,雖然兩個字符串的內容相同,但它們在內存中的地址是不同的。因此,使用.equals()方法比較它們的內容會返回true,而使用"=="操作符比較它們的地址會返回false

1. 重寫.equals()方法

學習過Java基礎的,應該知道Java所有類都默認繼承Obejct類,Object類中有一個.equals()方法

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

從代碼大家可以發現.equals()方法默認采用==操作符比較,如果子類沒有重寫equals()方法,那么就使用==操作符和equals()方法結果完全一樣--用于比較兩個對象內存地址是否相等。

但是實際情況是,有很多類重寫equals()方法,這是因為內存地址比較要求比較嚴格,不太符合現實中所有的場景需求,比如String類,進行比較時,大多只想判斷內容是否相等,并不太想知道內存地址是否相等(是否是一個對象)。

并且在深入理解Java字符串常量池文章中我們已經知道Java虛擬機為了減少內存開銷和提高性能特意給字符串開辟一塊空間-----字符串常量池

即推薦使用 String s = "Hello" 這種形式來創建字符串對象,而不是通過 new 關鍵字的方式,因為 new 需要在堆上開辟一塊新的空間。

1.1. String類的equals()方法

Jdk11的String類的equals()方法

public boolean equals(Object anObject) {
 //如果是同一個對象(即兩個引用指向內存中的同一塊地址),則直接返回true
    if (this == anObject) {
        return true;  
    }
 //如果是String類型的實例
    if (anObject instanceof String) { 
  //Object類型的對象強制轉換為String類型
        String aString = (String)anObject;
  //如果當前字符串對象和傳入的字符串對象的編碼方式相同
        if (coder() == aString.coder()) {
   //如果當前字符串和傳入的字符串都是Latin1編碼,則調用StringLatin1類的equals方法進行比較;如果其中一個或兩個字符串是UTF16編碼,則調用StringUTF16類的equals方法進行比較
            return isLatin1() ? StringLatin1.equals(value, aString.value)
                              : StringUTF16.equals(value, aString.value);
        }
    }
    return false;
}

特別說明:Latin1(也稱為ISO 8859-1)和UTF-16(Unicode轉換格式16位)是兩種不同的字符編碼方式

Latin1和UTF-16雖然是兩種編碼方式,但是差別不大,就拿 UTF-16 的來的equals()方法來看

@HotSpotIntrinsicCandidate
public static boolean equals(byte[] value, byte[] other) {
    if (value.length == other.length) {
        int len = value.length >> 1;
        for (int i = 0; i < len; i++) {
            if (getChar(value, i) != getChar(other, i)) {
                return false;
            }
        }
        return true;
    }
    return false;
}

注意:Java8和Java11的equals()方法源碼是有區別的JDK8的equals()方法

public boolean equals(Object anObject) {
    // 如果是同一個對象(即兩個引用指向內存中的同一塊地址),則直接返回true
    if (this == anObject) {
        return true;
    }
    // 如果是String類型的實例
    if (anObject instanceof String) {
        ////Object類型的對象強制轉換為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;
}

1.2. 示例說明

示例一:

new String("hello").equals("hello")

輸出結果是什么?

String類的equals方法比較的是字符串對象的內容是否相等,因為都是"Hello",所以結果是true

示例二:

new String("hello") == "hello";

輸出結果是什么?

==操作符比較的對象地址是否相等,==左邊是堆中創建對象,右邊是字符串常量池對象,雖然內容相等,但是地址不相等,所以結果是false

示例三:

new String("hello") == new String("hello");

輸出結果是什么?

new 出來的對象肯定是完全不同的內存地址,所以結果是false

示例四:

"hello" == "h"+"ello"

輸出結果是什么?

h和ello都在字符串常量池,所以編譯器在遇到+操作符的時候將其自動優化為hello,所以結果是true

示例五:

new String("hello").intern() == "hello"

輸出結果是什么?

new String("hello") 在執行的時候,會先在字符串常量池中創建對象,然后再在堆中創建對象;執行 intern() 方法的時候發現字符串常量池中已經有了‘hello’這個對象,所以就直接返回字符串常量池中的對象引用了,那再與字符串常量池中的‘hello’比較,所以結果是true

深入解析 String.intern()已經介紹過原因

2.  其他方法比較

除了.equals()方法和"=="操作符外,還有一些其他比較方法可以使用:

  • 1.Objects.equals()方法:這個靜態方法可以用于比較兩個對象是否相等,不需要在調用之前判斷對象是否為空。
Objects.equals("Hello", new String("Hello")); // 返回 true
  • 2.String類的.contentEquals()方法:這個方法可以用于比較字符串與任何字符序列(如StringBuffer、StringBuilder、String、CharSequence)是否相等。
String str = "Hello";
StringBuffer buffer = new StringBuffer("Hello");

System.out.println(str.contentEquals(buffer)); // 輸出 true
責任編輯:武曉燕 來源: springboot葵花寶典
相關推薦

2020-07-01 07:44:06

javaSE==equals

2023-10-12 08:25:18

Javaequals內存

2010-08-30 10:52:39

CSSclassid

2010-08-23 10:57:14

CSSclassid

2011-11-29 09:14:48

JavaError異常

2009-08-21 09:28:23

this與$(this

2024-03-19 14:41:08

C#操作符開發

2024-12-06 10:43:27

2010-08-30 10:37:54

DIVSPAN

2009-06-24 08:02:15

Hibernateupdate與save

2009-06-08 22:01:03

Java堆Java棧區別

2021-07-02 06:54:45

GoJavachannel

2011-05-23 11:22:37

2009-09-15 18:27:59

equals實現canEqualScala

2009-06-12 15:36:24

Hibernate fcreateQuery

2009-07-06 17:08:53

JDBC與ODBC的區

2013-06-14 10:45:15

NFVSDNOpenFlow

2009-02-16 09:25:43

EJBJavaBeanWebSphere

2009-06-12 09:52:49

StringStringBuffeJava

2014-07-24 10:00:21

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 免费国产一区二区 | 亚洲影音 | 亚洲欧美精品在线观看 | 亚洲国产视频一区 | 日韩欧美一区二区三区免费观看 | 成人在线视频免费播放 | 日韩成人在线观看 | 天天操夜夜操 | 欧美影院 | 亚洲精品视频三区 | 激情小视频 | 欧美一级免费黄色片 | 久久精品视频一区二区三区 | 久久久久无码国产精品一区 | 一级a爱片久久毛片 | 亚洲成色777777在线观看影院 | 国产97在线 | 日韩 | 男女视频在线观看网站 | 精品一区二区三区在线视频 | 日韩欧美在线播放 | 久久精品亚洲欧美日韩久久 | 久久精品色欧美aⅴ一区二区 | 91在线视频免费观看 | 97视频久久 | 国产视频二区 | 精品久久久久久久久久久久久久 | 亚洲一区中文字幕 | 国产精品久久九九 | 精品国产欧美一区二区三区成人 | 日韩中文字幕在线观看 | 午夜影院在线观看视频 | 在线观看国产视频 | 国产a区 | 在线视频日韩 | 日本一区二区视频 | 久久中文字幕一区 | 日韩人体视频 | 黑人一级片视频 | 日韩在线精品强乱中文字幕 | 国产在线中文字幕 | 国产一级片在线播放 |