簡體   English   中英

當toString()和hashCode()被覆蓋時,如何獲取java中對象的“對象引用”?

[英]How do you get the “object reference” of an object in java when toString() and hashCode() have been overridden?

我想在Java中打印對象的“對象引用”以進行調試。 即根據情況確保對象是相同的(或不同的)。

問題是有問題的類繼承自另一個類,它覆蓋了toString()和hashCode(),它們通常會給我id。

示例情況:運行多線程應用程序,其中我(在開發期間)想要檢查所有線程是否使用相同的資源對象實例。

你打算用它做什么(你想做什么會影響你需要調用的東西)。

hashCode ,如JavaDocs中所定義,表示:

盡可能合理,Object類定義的hashCode方法確實為不同的對象返回不同的整數。 (這通常通過將對象的內部地址轉換為整數來實現,但Java™編程語言不需要此實現技術。)

因此,如果您正在使用hashCode()來查明它是否是內存中的唯一對象,這不是一個好方法。

System.identityHashCode執行以下操作:

返回給定對象的相同哈希碼,就像默認方法hashCode()返回的一樣,無論給定對象的類是否覆蓋hashCode()。 空引用的哈希碼為零。

對於你正在做的事情,這聽起來像你想要的......但是你想做的事情可能不安全,這取決於庫的實現方式。

這就是我解決它的方式:

Integer.toHexString(System.identityHashCode(object));

無論對象的hashCode或equals的實現如何,Double equals ==將始終基於對象標識進行檢查。 當然 - 確保您正在比較的對象引用是volatile (在1.5+ JVM中)。

如果你真的必須擁有原始的Object toString結果(雖然它不是你的示例用例的最佳解決方案),Commons Lang庫有一個方法ObjectUtils.identityToString(Object)可以做你想要的。 來自JavaDoc:

public static java.lang.String identityToString(java.lang.Object object)

如果類沒有覆蓋toString本身,則獲取由Object生成的toString。 null將返回null。

 ObjectUtils.identityToString(null)         = null
 ObjectUtils.identityToString("")           = "java.lang.String@1e23"
 ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"

你不能安全地做你想要的,因為默認的hashCode()可能不會返回地址,並且已經提到過,具有相同hashCode的多個對象是可能的。 實現所需內容的唯一方法是實際覆蓋有問題對象的hashCode()方法,並保證它們都提供唯一值。 在你的情況下這是否可行是另一個問題。

為了記錄,我在WAS服務器中運行的IBM VM中遇到了具有相同默認哈希碼的多個對象。 我們遇到了一個缺陷,即由於這個原因,被放入遠程緩存的對象會被覆蓋。 從那時起,這讓我大開眼界,因為我認為默認的哈希碼也是對象的內存地址。

為您的所有實例添加唯一ID,即

public interface Idable {
  int id();
}

public class IdGenerator {
  private static int id = 0;
  public static synchronized int generate() { return id++; }
}

public abstract class AbstractSomething implements Idable {
  private int id;
  public AbstractSomething () {
    this.id = IdGenerator.generate();
  }
  public int id() { return id; }
}

從AbstractSomething擴展並查詢此屬性。 在單個虛擬機內部是安全的(假設沒有游戲與類加載器一起玩以繞過靜態)。

我們可以簡單地從對象類的tostring復制代碼來獲取string的引用

class Test
{
  public static void main(String args[])
  {
    String a="nikhil";     // it stores in String constant pool
    String s=new String("nikhil");    //with new stores in heap
    System.out.println(Integer.toHexString(System.identityHashCode(a)));
    System.out.println(Integer.toHexString(System.identityHashCode(s)));
  }
}

暫無
暫無

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

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