In terms of how the Oracle is actually implemented is just a detail which isn't specified. A reference is a pointer (possibly compressed, see Compressed Oops) to the object's header and data.
In the header is a pointer to the class definition. You can see this using Unsafe. In this case, I have assumed compressed oops have to be turned off to keep things simple.
WARNING This is not suitable for work, only try this at home. ;)
When run on Oracle Java 8. Another JVM version might be different.
Object i = 0x12345678;
// set the System.identityHashCode
UNSAFE.putInt(i, 1L, 0x23456789);
System.out.printf("identityHashCode: %x%n", System.identityHashCode(i));
Object[] obj = {i};
assert Unsafe.ARRAY_OBJECT_INDEX_SCALE == 8; // 8 bytes per reference.
long address = UNSAFE.getLong(obj, (long) Unsafe.ARRAY_OBJECT_BASE_OFFSET);
System.out.printf("address: %x%n", address);
for (int j = 0; j < 24; j++)
System.out.printf("%02x ", UNSAFE.getByte(address + j) & 0xFF);
System.out.println();
System.out.printf("`i` is a %s and is %x%n", i.getClass(), i);
// now some really scary sh!t
long longClassPointer = UNSAFE.getLong(0L, 8L);
UNSAFE.putLong(i, 8L, longClassPointer);
System.out.printf("`i` is now a %s and is %x%n", i.getClass(), i);
prints the hashCode set, the 64-bit address, the contents of the object and header, and finally what happens if you change the klass pointer to that of a Long class instead.
identityHashCode: 23456789
address: 1d3f9ca00
01 89 67 45 23 00 00 00 a0 74 f8 26 00 00 00 00 78 56 34 12 00 00 00 00
`i` is a class java.lang.Integer and is 12345678
`i` is now a class java.lang.Long and is 12345678
for the complete code https://github.com/peter-lawrey/Performance-Examples/blob/master/src/main/java/vanilla/java/unsafe/AccessRawMemoryMain.java