On Mon, 3 Jul 2000, Christopher Smith wrote:
> --On Monday, July 03, 2000 4:24 PM -0700 Mo DeJong <[EMAIL PROTECTED]>
> wrote:
> > Exception in thread "main" tcl.lang.TclRuntimeError:
> >
> > (find) table entry "SomeObject.1512497281" mapped to an invalid
> > entry,
>
> I'm not familiar with the Jacl code base, but this error does not jibe with
> my own experiences with this method under heavy load situations. Is it
> possible that this is a bug in the Jacl engine? A real easy test would be
> take the two object which are supposedly using the same identity hash and
> test if the two objects are indeed identical.
I do not think this is an error in any Jacl code, but if you can
prove me wrong please do so. The error condition is only raised
if the two objects have the same identityHashCode and yet
fail the "obj1 == obj2" test.
If you want to see the source, it is in the method findInReflectTable()
in the file tcljava/src/tcljava/tcl/lang/ReflectObject.java, the
CVSROOT is :pserver:[EMAIL PROTECTED]:/cvsroot and the module
name is tcljava.
Here is the extended output from the error. Note how two different
objects (you can tell they are different because the == test and
the .equals() tests both fail) both return the identityHashCode
1512497281.
(find) table entry "SomeObject.1512497281" mapped to an invalid entry,
Searched (Class = "SomeObject" identityHashCode = "1512497281" hashCode =
"1512497281")
Found ( refID = "java0x464c" Class = "SomeObject" identityHashCode =
"1512497281" hashCode = "1512497281")
Equality Tests ( Class == "true" Object == "false" Object.equals() ==
"false" I
nterp == "true")
at tcl.lang.ReflectObject.findInReflectTable
at tcl.lang.ReflectObject.makeReflectObject
at tcl.lang.ReflectObject.newInstance
> Other items worth noting:
>
> 1) By the strictest of interpretations of the specifications of the
> specifications, it is in fact legal for two different objects to return the
> same value for System.identityHashCode() so long as you don't test the
> values at the same time.
http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html#hashCode()
http://java.sun.com/j2se/1.3/docs/api/java/lang/System.html#identityHashCode(java.lang.Object)
The SDK docs (noted above) say the following:
"As much as is reasonably practical, the hashCode method defined by class
Object does return distinct integers for distinct objects. (This is
typically implemented by converting the internal address of the object
into an integer, but this implementation technique is not required
by the Java TM programming language.)
> 2) If the previous object has been garbage collected, this in theory frees
> up the hash code for another object to use. Make sure that you really have
> two objects and this is not just a left over value from an already GC'd
> object.
No, the other object has not been garbage collected. How could I
compare one object to another if I did not have a valid ref
sitting around?
> My suspicion is that you are discovering that the JDK 1.2+ VM's move
> objects around in memory when they GC. This potentially results in
> different return values for System.indentityHashCode() for the same object
> before and after a GC.
The object in the table might have been moved by the GC, but it still returns
the same hash code as it did when I put it in the table. You can see
that this is the case from the extended output where I call the
hash code methods again on the searched and found objects and they
both return the same id.
> So the assertion that:
>
> static MyClass {
> private static MyClass firstInstance = new MyClass();
> private static int fiHashCode = System.identityHashCode(firstInstance);
> public bool assert() {
> if (this == firstInstance)
> return true;
> else
> return fiHashCode != (System.identityHashCode(this));
> }
> }
>
> MyClass.assert() will never return false is not true.
>
> --Chris
No it is more like this (some quick pseudo code).
void add(Class c, Object obj) {
StringBuffer sb ...
Hashtable table = ...
sb.append( c.getName() );
sb.append( '.' );
sb.append( System.identityHashCode(obj) );
Object intable = table.get( sb.toString() );
if (intable != null && intable != obj) {
assert();
} else {
table.put( sb.toString(), obj );
}
}
The check is not to see if the same hash code is
ever reused, it is only to see if two different
objects has to the same id at the same time.
My reading of the docs seems to indicate that
this is exactly what the identityHashCode()
methods is designed for. Would you agree?
Mo DeJong
Red Hat Inc
----------------------------------------------------------------------
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]