オブジェクトのIDを取得するには (identityHashCode / object_id)

Java / Scala / Groovy

Signature:

すべてのオブジェクトにある hashCode メソッドは、別々のオブジェクトでもそのオブジェクトが表す値が等しければ同じ値を返すが、この identityHashCode は別々のオブジェクトであれば異なる値を返すのが原則。とはいえ、ハッシュ値なので、異なる値が保証されているわけではなく、別々のオブジェクトで値が衝突する可能性はゼロではない。

hashCode のデフォルト実装は identityHashCode と同じ値を返す。

hashCodeをオーバーライドしても、オーバーライド前のhashCodeの値を identityHashCodeで取得できる。

Python

idという組み込みの関数でオブジェクトのIDを取得できる。同時に存在する異なるオブジェクトは異なるIDを持つことが保証されているが、オブジェクトの生存期間が重なっていなければ、同じIDになる可能性は理論上はある。

id | Python 2.7 documentation
http://docs.python.jp/2/library/functions.html#id

id | Python 3 documentation
http://docs.python.jp/3/library/functions.html#id

Ruby

すべてのオブジェクトにある object_id メソッドを使うと、オブジェクトのIDを取得できる。

Object#object_id メソッド | Ruby 1.9.3 リファレンスマニュアル
http://docs.ruby-lang.org/ja/1.9.3/method/Object/i/object_id.html

JRuby

RubyとJavaのどちらの方法でもオブジェクトのIDを取得できる。両者は同じ値になるので、たぶんJRubyでのobject_idメソッドは java.lang.System.identityHashCode で実装しているのだと思う。

require 'java'

jobj = java.lang.Object.new;

p jobj
# => #<Java::JavaLang::Object:0x638951ca>

p java.lang.System.identityHashCode(jobj)
# => 1669943754

p jobj.hashCode
# => 1669943754

p jobj.object_id
# => 1669943754

この実行例は実行するごとに出力が異なるが、3つの整数は常に同じになる。 1つ目の #<Java::JavaLang::Object:0x638951ca> という出力も最後の方の16進数を10進数に変換すると3つの整数と一致する。

JavaのhashCodeがオーバーライドされている場合でも、hashCode以外は一致する。

require 'java'

jobj = java.lang.String.new("abc")

p jobj
# => #<Java::JavaLang::String:0x1367d679>

p java.lang.System.identityHashCode(jobj)
# => 325572217

p jobj.hashCode
# => 96354

p jobj.object_id
# => 325572217
このサイトは筆者(hydrocul)の個人メモの集合です。すべてのページは永遠に未完成です。