簡體   English   中英

關於 java 字符串結果的混淆

[英]confusion about the results of java String

class Test{
       public static void main(String s[]){
              String s1="welcome",s2="come";        
              System.out.println(s1==("wel"+"come"));    //prints : true
              System.out.println(s1==("wel"+s2));        //prints : false
      }
}

我想知道為什么這兩種 println 方法都會給出不同的結果。 請詳細說明。

==總是比較引用本身。

在第一個比較中,常量字符串表達式"wel" + "come"compile-time進行評估,因此您最終會得到與用於初始化s1的文字相同的內部引用。

在第二種情況下,在執行時執行連接,創建一個字符串。

要比較兩個字符串的內容是否相等(而不是檢查兩個引用是否指向同一個對象),請使用equals

System.out.println(s1.equals("wel" + "come"));
System.out.println(s1.equals("wel" + s2));
String s1="welcome",s2="come";        
System.out.println(s1==("wel"+"come"));    //prints : true

這些是編譯時常量,因此編譯器可以將代碼內聯到

System.out.println(s1==("welcome"));    //prints : true

這里,第二部分不是編譯時常量,因此編譯器無法優化,因此在運行時創建了一個新的 String object:

System.out.println(s1==("wel"+s2));        //prints : false

嘗試通過將字符串與“==”運算符進行比較來測試字符串是否相等是一件壞事。 字符串是對象,因此當使用“==”時,您是在比較兩個對象的引用,而不是對象本身。

嘗試改用 equals() 方法。

==執行 object 參考相等測試。 請改用String.equals()方法(測試字符串值是否相等)。

s1.equals("wel" + s2);

您的第二種方法在運行時進行測試。 編譯器創建新字符串 object 並將 object 引用與新字符串 object 進行比較。

在 java ==通過引用比較對象,因此只有當兩個變量指向同一個 object 時才會返回 true。

在第一種情況下,Java 編譯器將意識到“wel”+“come”是一個常量,並為 s1 和“wel”+“come”使用相同的 object(指向常量池的指針)。 在第二種情況下,Java 編譯器將不知道它是一個常量,並且在運行時 Java 將創建一個新的 object 並且在執行“wel”+s2 時比較將失敗。

在 Java 中,應始終且無一例外地使用.equals方法來比較兩個字符串。 如果使用==對字符串進行比較,您 IDE 也應該給您一個警告。

要比較字符串,您應該使用 String.equals 方法。

這是因為編譯器在編譯源代碼(優化它)之前“wel”+“come”解析為“welcome” 表達式可以在編譯之前靜態解析,編譯器會這樣做。

然后,運算符 == 在前一種情況下返回 true,因為兩者都是存儲在字符串池中的完全相同的 object“歡迎”。

就像你這樣做一樣:

Java 沒有運算符重載,如 C++ 和 C# 有。 因此,這意味着==運算符總是比較引用。 您正在比較的字符串可能相同,但它們具有不同的引用。 什么原因導致false

但是為什么會有真實的結果呢? 好吧,Java 創建了一個字符串池。 所有字符串文字將在編譯時放入字符串池中。 這意味着:

String literalString1 = "foo";
String literalString2 = "foo";
literalString1 == literalString2 // true

因為它都是對字符串池的引用。

但是一旦你開始構建字符串(使用+ ),它就會在堆上創建的字符串。 然而,Java 編譯器很聰明,在編譯時構建了兩個字符串文字。

"wel"+"come" == "welcome"

因為您是在運行時構建它們。 編譯器會檢測到"wel" + "come"是一個字符串字面量,並將其放入字符串池中。 "welcome"也是一個字面量,將搜索字符串池以檢查該字面量是否已經在字符串池中。 當然它會找到它並使用相同的參考。

事實上,在 Java 中,字符串可以被視為 Object 或原始類型。

作為原始類型:

String text1 = "a";

作為 Object:

String text2 = new String("a");

但在 java ==總是比較參考而不是值。

當我寫這段代碼時:

text1 == text2返回false ,現在text2 + "b" == "ab"也返回false

因為它將運行時創建的 object 與常量進行比較,這適用於您的第二種情況,在前一種情況下,“wel”+“come”將被 java 編譯器視為“歡迎”,並且作為常量,它與您的常量相同定義了你的字符串變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM