Quantcast
Channel: Absolutely No Machete Juggling » java
Viewing all articles
Browse latest Browse all 10

Getting A Java Object’s Reference ID

$
0
0

UPDATE: A number of commenters have pointed out that I’m totally wrong here. Please don’t do this.

When you take an object that has not defined a toString method, it prints out strings that look like these:

Object@3e25a5
Car@19821f

Many people believe that this is the memory location of the object, which isn’t really accurate, as it’s the reference ID. It is, however, a string that uniquely identifies the object in memory, so the misconception is understandable.

A friend recently asked me if there was any way to get that “address” on an object that has overridden toString. Once toString has been overridden, calling it will bypass this default implementation.

Since his internet search didn’t pull anything up, I figured I’d blog about the answer to his conundrum in case anyone else is ever curious about it.

It may be surprising, but calling hashCode() actually gives you this value. The hashCode method doesn’t hash the actual object by it’s value, but by it’s identity, meaning its reference ID.

To illustrate this simply, take a look at the following code snippet. It creates two identical objects, then adds them to a HashMap, and prints out the size of the HashMap.

Car car1=new Car("Chevy", "Blazer");
Car car2=new Car("Chevy", "Blazer");

AbstractMap<Car, String> map=new HashMap<Car, String>();
map.put(car1, "Got it");
map.put(car2, "Got it");

System.out.println("Size is: "+map.size());

HashMap works by calling hashCode() on the objects going into the map. You might expect for the size to be 1, since the two cars are the same. However, they do not have the same hashCode, because hashCodes are, by default, identity-based. Since the two objects take up two unique spots in memory (as they were instantiated separately), they have different hashCodes, and thus the size of the map is 2.

This means that you can get the reference ID, the thing after the @ in default toString() implementations, simply by calling hashCode() on the object. It comes back as an int, but it has the same value as the hexadecimal string would in the default toString() implementation.

However, it’s really not a good idea to override toString() without also overriding hashCode() and equals(), so it stands to reason hashCode will be overridden with a value-based hashing scheme in whatever class you’re working with.

Fear not, however, as the System object will actually give you access to the identity-based hashcode on any object, even if the class it is an instance of has overridden hashCode().

You can also handily convert an integer to a hex string using the Integer class, so you can get the value that would come after the @ in a default toString() implementation by calling this:

Integer.toHexString(System.identityHashCode(object)) 

Viewing all articles
Browse latest Browse all 10

Trending Articles