java---String的比較問題

public class StringCompare {
  public static void A() {
    String str1 = "java";
    String str2 = "java";
    System.out.println(str1 == str2);  //true
  }
  public static void B() {
    String str1 = new String("java");
    String str2 = new String("java");
    System.out.println(str1 == str2);  //false
  }
  public static void C() {
    String str1 = "java";
    String str2 = "blog";
    String s = str1 + str2;
    System.out.println(s == "javablog");  //false
  }
  public static void C2() {
    String str1 = "javablog";
    String str2 = "java"+"blog";    //在編譯時被優化成String str2 = "javablog";
    System.out.println(str1 == str2);  //true
  }
  public static void D() {
    String s1 = "java";
    String s2 = new String("java");
    System.out.println(s1.intern() == s2.intern());  //true
  }

  public static void E() {
    String str1 = "java";
    String str2 = new String("java");
    System.out.println(str1.equals(str2));  //true
  }
  
  public static void main(String[] args){
    A();
    B();
    C();
    C2();
    D();
    E();
  }
}

輸出============

true
false
false
true
true
true

 

 

問題1:
String s = new String("abc");   

String s1 = "abc";   

String s2 = new String("abc");   

System.out.println(s == s1);   

System.out.println(s == s2);   

System.out.println(s1 == s2);  

String s = new String("abc");
String s1 = "abc";
String s2 = new String("abc");

System.out.println(s == s1);
System.out.println(s == s2);
System.out.println(s1 == s2);


請問以上程序執行結果是什麼?

第一句執行後內存中有兩個對象,而不是一個。一個由new String("abc")中的"abc"在String Pool裏生成一個值爲"abc"的對象;第二個由new在堆裏產生一個值爲"abc"的對象,該對象完全是String Pool裏的"abc"的一個拷貝。變量s最後指向堆中產生的"abc"對象;
第二句執行時,s1先去String Pool找是否有值爲"abc"的對象,很顯然在上一步中java已經在String Pool裏生成一個"abc"對象了,所以s1直接指向String Pool中的這個"abc";
第三句中又有一個new,在java中凡遇到new時,都會在堆裏產生一個新的對象。因此,該句執行後堆裏又多了一個"abc"對象,這與執行第一句後生成的"abc"是不同的兩個對象,s2最後指向這個新生成的對象。
因此,執行後面的打印語句的結果是三個false

問題2:
System.out.println(s == s.intern());   

System.out.println(s1 == s1.intern());   

System.out.println(s1.intern() == s2.intern());  

System.out.println(s == s.intern());
System.out.println(s1 == s1.intern());
System.out.println(s1.intern() == s2.intern());


請問以上程序執行結果是什麼?

設s爲String類型的變量,當執行s.intern()時,java先在String Pool裏找與字符串變量s相等(用equals()方法)的字符串,若有則將其引用返回;若沒有則在String Pool裏創建一個與s的值相等的字符串對象,並將其引用返回。從中我們可以總結出intern()方法無論如何都將返回String Pool裏的字符串對象的引用。
因此,以上程序執行的結果是falsetruetrue
PS:設s和t爲兩個字符串變量,若有s.equals(t),必有s.intern() == t.intern();
PS:"=="永遠比較的是兩邊對象的地址是否相等。

問題3:
String hello = "hello";   

String hel = "hel";   

String lo = "lo";   

System.out.println(hello == "hel" + "lo");   

System.out.println(hello == "hel" + lo);  

String hello = "hello";
String hel = "hel";
String lo = "lo";
System.out.println(hello == "hel" + "lo");
System.out.println(hello == "hel" + lo);


請問以上程序執行結果是什麼?

前三句在String Pool裏分別產生“hello”、“hel”、“lo”三個常量字符串對象
當做第一個加法連接時,+號兩邊都是常量字符串,java就會將兩者拼起來後到String Pool裏找與之相等(用equals)的字符串,若存在則將其地址返回;不存在則在String Pool裏新建一個常量對象,其值等於拼接後的字符串,並將其地址返回。
第二個+號兩邊有一個是變量,此時,java會在堆裏新建一個對象,其值是兩字符串拼接後的值,此時返回的地址是堆中新對象的地址。
所以,第一句做+連接後返回String Pool中“hello”的地址,顯然與變量hello的地址相等;
第二句返回的是堆中地址,顯然與變量hello的地址不等;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章