L的代碼很簡單public class L {}public class Synchronized1 { public static void main(String[] args) { L l=new L();// System.out.println(l.toString()); System.out.println(ClassLayout.parseInstance(l).toPrintable()); }}取消注釋,再次運行代碼會得到不同的結果,或者是兩個完全不同的結果。我想知道造成這個結果的原因是什么?不僅調用 toString() 會影響結果,調用對象上的其他方法也會影響結果,例如 hashCode()
1 回答

holdtom
TA貢獻1805條經驗 獲得超10個贊
您的空類class L
使用toString()
從 繼承的默認值class Object
。
默認toString()
調用hashCode()
.
正如您已經看到的,hashCode()
似乎也影響對象的標頭。
因此,本質上,問題可以重述為“為什么調用會hashCode()
改變我的對象的標頭?”
正如其他人已經在評論中指出的那樣,發(fā)生這種情況是因為在您正在使用的特定 JVM 實現(xiàn)中,第一次調用時會計算對象的 hashCode,然后將其緩存在標頭中,以便后續(xù)hashCode()
調用hashCode()
可以只返回緩存的值,而無需再次重新計算。
除了性能之外,這樣做可能還有更重要的原因。
根據(jù)您使用的 JVM 計算哈希碼的方式,計算中可能存在隨機性,或者可能存在不斷遞增的數(shù)字種子,因此后續(xù)嘗試重現(xiàn)對象的哈希碼可能無法實現(xiàn)生成與第一次計算完全相同的值。這意味著第一次計算必須確定之后的哈希碼值。
添加回答
舉報
0/150
提交
取消