2015-10-10 79 views
1

我想確認是否創建了兩個字符串變量指向相同的內存。我的方式與普通類做了如何確認(或獲取字符串的對象轉義)如果字符串中創建的字符串?

Ideone a=new Ideone(); 
Ideone b=a; 

System.out.println(a+" "+b); 

輸出

[email protected] [email protected] 

這裏產生的輸出是不準確的記憶地址,但它給了相同的十六進制代碼,並且我可以說它們都指向相同的內存地址或值。

但在字符串的情況下

String a="helloworld"; 
String b="hello"; 
String c=b+"world"; 
System.out.println(a+" "+c); 

輸出

helloworld helloworld 

其預期的輸出,我知道a,b,c在池中創建的,因爲他們是編譯時間常數和ac做不指向相同的內存。但有沒有什麼辦法可以得到像[email protected]這樣的字符串的對象表示方式來獲取該對象的十六進制代碼來確認ac不指向相同的內存? 因爲在創建字符串的情況下new String("helloworld")新內存分配給字符串。

我已經搜索過它,但dint找到類似於我的問題的任何東西。

在此先感謝。

回答

2

正如JLS

字面解釋總是一個字符串,是指String類的同一個實例。

但是,它也取決於你如何形成String對象。
示例:調用new String("abcd")就像已經有字符串參數「abcd」,但仍強制JVM創建一個新的String引用。檢查更多信息部分...

正如你在你的例子中說的,你不能得到指針ID,但你仍然可以通過調用toString()方法得到一些唯一的字符串,使用它符合它們的唯一類型。但是,的toString的實現Object.toString()

public String toString() { 
    return getClass().getName() + "@" + Integer.toHexString(hashCode()); 
} 

因此,它是的hashCode

根據Hashcode契約,如果兩個對象相等,則表示它們的hashCode必須相同,但反之亦然。

的hashCode從spec常規協定是:

  • 只要它是一個 執行的Java應用程序在同一對象上多次調用,hashCode方法必須始終 返回相同的整數,如果沒有使用等於 的對象的比較被修改。該整數不必保持 從應用程序的一次執行到同一應用程序的另一次執行 的一致。

  • 如果兩個對象根據 equals(Object)方法相等,則對兩個對象的每個對象調用hashCode方法必須產生相同的整數結果。

  • 不要求 ,如果兩個對象根據 等號不相等(java.lang.Object)方法,則調用每個兩個對象的 hashCode方法必須產生不同的整數結果。但是,程序員應該知道,爲不相等的對象生成不同的 整數結果可能會提高散列表的性能。

所以,要麼使用==運營商,這將使身份/參考檢查或者必須信任JVM實現的字符串表達式總是指向唯一的參考,否則JVM沒有遵守規範。


更多信息:

這是在上述JLS規範給出的例子。

package testPackage; 
class Test { 
    public static void main(String[] args) { 
     String hello = "Hello", lo = "lo"; 
     System.out.print((hello == "Hello") + " "); 
     System.out.print((Other.hello == hello) + " "); 
     System.out.print((other.Other.hello == hello) + " "); 
     System.out.print((hello == ("Hel"+"lo")) + " "); 
     System.out.print((hello == ("Hel"+lo)) + " "); 
     System.out.println(hello == ("Hel"+lo).intern()); 
    } 
} 

class Other { static String hello = "Hello"; } 

和編譯單元:

package other; 
public class Other { public static String hello = "Hello"; } 

產生輸出:

真真真真

該實施例說明六個點:

  • 同一個包中相同類中的字符串表示對同一個String對象的引用。

  • 同一包中不同類中的文字字符串表示對同一個String對象的引用。

  • 不同包中不同類中的文字字符串同樣代表對同一個String對象的引用。

  • 由常量表達式計算出的字符串在編譯時計算出來,然後視爲它們是文字。

  • 在運行時通過串聯計算的字符串是新創建的,因此是不同的。

  • 明確實習計算的字符串的結果與任何具有相同內容的預先存在的文字字符串是相同的字符串。

+1

我很困惑,其答案選擇,因爲他們都是很好的,但我喜歡你的回答除了其他的是你hashCose javaspecs.Thanks – silentprogrammer

1

我想確認是否創建了兩個字符串變量指向相同的內存

您可以檢查任何對象引用在與==運營商相同的對象指向。這就是你需要:

boolean sameObject = (a == b); 

有沒有什麼方法可以讓我得到像串串的對象表示@ 23122

是的,如果你真的想要的是:

System.out.println(a.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(a))); 

但這不會有用,因爲兩個不同的對象可能具有相同的哈希碼。散列碼不一定是內存地址,並且usually isn't

+0

但'儘可能合理的實際,由類Object定義的hashCode方法確實返回不同對象的不同整數。' – EJP

+0

這是愚蠢的我我記得'=='參考檢查:) – silentprogrammer

1

首先,你的方法是錯誤的。您正在計算沒有從Object覆蓋toString()方法的類的字符串表示形式。

Object.toString方法,如果不被重寫時,返回一個由類,@的名稱的字符串,並且對象的哈希碼。這不是它的地址,它與地址無關。因此,具有相同散列碼的兩個對象將返回相同的字符串。

爲了證明,讓我們來看看它覆蓋equalshashCode但不會覆蓋toString方法的小類:

class MyInteger { 
    int myInteger; 

    public MyInteger(int myInteger) { 
     this.myInteger = myInteger; 
    } 

    public int getInteger() { 
     return myInteger; 
    } 
    @Override 
    public boolean equals(Object obj) { 
     if (obj instanceof MyInteger) { 
      return myInteger == ((MyInteger)obj).myInteger; 
     } 
     return false; 
    } 

    @Override 
    public int hashCode() { 
     return myInteger; 
    } 
} 

現在,讓我們來試試你的區分兩個不同的對象的方法:

MyInteger int1 = new MyInteger(1004); 
MyInteger int2 = new MyInteger(1004); 
System.out.println(int1+" "+int2); 

印刷會是這樣的結果:

[email protected] [email protected]

但很明顯,int1int2指向兩個不同的對象,用new明確創建!

因此,忘記這種方法 - 它沒有意義。


現在,你怎麼知道兩個對象是不同的?很簡單,請將參考文獻與==!=進行比較。

所以,如果我嘗試了上述

System.out.println(int1 != int2); 

其結果將是true

這是相同的字符串:

String a="helloworld"; 
String b="hello"; 
String c=b+"world"; 
String d="hello"; 
System.out.println("a refers to a different object than c? " + (a != c)); 
System.out.println("b refers to a different object than d? " + (b != d)); 

印刷的結果將是:

a refers to a different object than c? true 
b refers to a different object than d? false
相關問題