How to Tell Which Class an Object Is

M

Mike Schilling

message
Object#equals (Object) determines if another object is equivalent to
`this`. The intrinsic == operator determines if two objects are the same
object. These operations have distinct semantics, regardless of whether
`this` is a String, a Class, or an ArbitraryComplexObject.

The former can (and, as you've so helpfully pointed out, often is) be
implemented in terms of the latter, for objects with no sensible
definition of equivalence. This doesn't make them the same operation.

They do the same thing for Class instances, which was the subject being
discussed.
 
C

Chris Uppal

Mike said:
They do the same thing for Class instances, which was the subject being
discussed.

Incidentally, do you know of any reason why this /must/ be the case -- i.e. why

Object o = //...
o.getClass() == o.getClass()

could never be false, when:

o.getClass.equals(o.getClass())

was true ? It obviously makes sense for class object to behave in that way,
but the only guarantee I've been able to find so far is the rather indirect,
even subtle, observation that static synchronised blocks and methods are
defined to be synchronised on "the" class object.

-- chris
 
M

Mike Schilling

Chris Uppal said:
Incidentally, do you know of any reason why this /must/ be the case --
i.e. why

Object o = //...
o.getClass() == o.getClass()

could never be false, when:

o.getClass.equals(o.getClass())

was true ? It obviously makes sense for class object to behave in that
way,
but the only guarantee I've been able to find so far is the rather
indirect,
even subtle, observation that static synchronised blocks and methods are
defined to be synchronised on "the" class object.

That's the only direct evidence I know of either, that one can be sure that

static synchronized void method()

and

lock (Class1.getClass)

lock the same object.

By the way, I recently learned that in .NET, one should *not* synchronize on
class objects (or type objects, as it calls them). The reason is that a
single class object could be used in two "application domains" (which more
or less means two .NET instances running in the same OS process), so you
could be locking code running in a different application entirely. Talk
about obscure, unreproducible errors!
 
M

Mark Thornton

Chris said:
Mike Schilling wrote:




Incidentally, do you know of any reason why this /must/ be the case -- i.e. why

Object o = //...
o.getClass() == o.getClass()

could never be false, when:

o.getClass.equals(o.getClass())

was true ? It obviously makes sense for class object to behave in that way,
but the only guarantee I've been able to find so far is the rather indirect,
even subtle, observation that static synchronised blocks and methods are
defined to be synchronised on "the" class object.

-- chris

From the language specification

http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.2

"Well-behaved class loaders maintain these properties:


Given the same name, a good class loader should always return the same
class object. "

Which leaves open the possibility of malicious (or broken) class
loaders. There may be more on this in the VM specification document.

Mark Thornton
 
O

Owen Jacobson

It would make sense to me for the same class loaded by two different
ClassLoaders to be .equal(...) to each other but not == to each other:
they're equivalent classes, but not the same class.
By the way, I recently learned that in .NET, one should *not*
synchronize on class objects (or type objects, as it calls them). The
reason is that a single class object could be used in two "application
domains" (which more or less means two .NET instances running in the
same OS process), so you could be locking code running in a different
application entirely. Talk about obscure, unreproducible errors!

Ooof. That's horrible. I hope that's a consequence of objects being
generally visible between processes (with the concurrency nightmares that
entails) rather than being merely an implementation quirk of the runtime.
 
M

Mark Thornton

Owen said:
It would make sense to me for the same class loaded by two different
ClassLoaders to be .equal(...) to each other but not == to each other:
they're equivalent classes, but not the same class.

No, I think that would lead to trouble.
 
O

Owen Jacobson

No, I think that would lead to trouble.

From the API docs, the class "equals" method is inherited unaltered from
Object, so in practice I agree with you that anything written assuming the
above could be in trouble, and further that altering Class to behave that
way would probably break a lot of existing code.

In principle, given that Java allows multiple class "domains" via multiple
ClassLoader instances, equivalence might well have been given the above
semantics. What specific problems do you see?

-Owen
 
C

Chris Uppal

Mike Schilling wrote:

By the way, I recently learned that in .NET, one should *not* synchronize
on class objects (or type objects, as it calls them). The reason is that
a single class object could be used in two "application domains" (which
more or less means two .NET instances running in the same OS process), so
you could be locking code running in a different application entirely.
Talk about obscure, unreproducible errors!

Crickey!

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,000
Messages
2,570,252
Members
46,848
Latest member
CristineKo

Latest Threads

Top