Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to Tell Which Class an Object Is

0 views
Skip to first unread message

kvns...@hotmail.com

unread,
Sep 29, 2005, 3:06:30 PM9/29/05
to
Below I'm including the source code for a Java application that con-
tains an interface <If> and two classes that implement it, <Abc> and
<Def>. <Rndm.open> flips a coin and returns an object of class <Abc>
half the time and an object of class <Def> the other half of the time.
Then in my <main> method I call <Rndm.open> and assign its value to
object <xyz>. How can I tell which class <xyz> is, <Abc> or <Def>? I
wrote the code below to help me tell, but when I try to compile it I
get the error message:

Gc.java:36: cannot find symbol
symbol : variable Abc
location: class Gc
if (xyz.getClass() == Abc)
^
1 error

Can anyone see what I'm doing wrong? Any feedback on this would be
greatly appreciated. My code follows:

import java.util.Random;

interface If
{
}

class Abc implements If
{
}

class Def implements If
{
}

class Rndm
{
static If open ()
{
Random rndm = new Random();

if (rndm.nextInt( 2) == 0)
{ return new Abc();
}
else
{ return new Def();
}
}
}

public class Gc
{
public static void main ( String[] arguments)
{
If xyz = Rndm.open();

if (xyz.getClass() == Abc)
{ System.out.println( "Method <open> generated an <Abc>.");
}
else
{ System.out.println( "Method <open> generated an <Def>.");
}
}
}

---Kevin Simonson

"You'll never get to heaven, or even to LA,
if you don't believe there's a way."
from _Why Not_

Chiron Paixos

unread,
Sep 29, 2005, 4:17:45 PM9/29/05
to
On 29 Sep 2005 12:06:30 -0700, kvns...@hotmail.com wrote:

>Below I'm including the source code for a Java application that con-
>tains an interface <If> and two classes that implement it, <Abc> and
><Def>. <Rndm.open> flips a coin and returns an object of class <Abc>
>half the time and an object of class <Def> the other half of the time.
>Then in my <main> method I call <Rndm.open> and assign its value to
>object <xyz>. How can I tell which class <xyz> is, <Abc> or <Def>? I
>wrote the code below to help me tell, but when I try to compile it I
>get the error message:
>
> Gc.java:36: cannot find symbol
> symbol : variable Abc
> location: class Gc
> if (xyz.getClass() == Abc)
> ^
> 1 error

If you insist on using getClass() look at the following example which
uses a Class object to print the Class name of an object:

void printClassName(Object obj) {
System.out.println("The class of " + obj +
" is " + obj.getClass().getName());
}

Maybe you should consider using instanceOf
--
Never give up the fight for freedom - a fight which,
though it may never end, is the most ennobling known to man.
(Ronald Reagan)

Dave Glasser

unread,
Sep 29, 2005, 4:32:32 PM9/29/05
to
kvns...@hotmail.com wrote on 29 Sep 2005 12:06:30 -0700 in
comp.lang.java.programmer:

>Below I'm including the source code for a Java application that con-
>tains an interface <If> and two classes that implement it, <Abc> and
><Def>. <Rndm.open> flips a coin and returns an object of class <Abc>
>half the time and an object of class <Def> the other half of the time.
>Then in my <main> method I call <Rndm.open> and assign its value to
>object <xyz>. How can I tell which class <xyz> is, <Abc> or <Def>? I
>wrote the code below to help me tell, but when I try to compile it I
>get the error message:
>
> Gc.java:36: cannot find symbol
> symbol : variable Abc
> location: class Gc
> if (xyz.getClass() == Abc)


Use the class literal for Abc, which is Abc.class:

if(xyz.getClass().equals(Abc.class)) {
...

Using the == operator would probably also work:

if(xyz.getClass() == Abc.class) {
....

but I think using .equals() is safer.


--
Check out QueryForm, a free, open source, Java/Swing-based
front end for relational databases.

http://qform.sourceforge.net

If you're a musician, check out RPitch Relative Pitch
Ear Training Software.

http://rpitch.sourceforge.net

kvns...@hotmail.com

unread,
Sep 29, 2005, 4:33:19 PM9/29/05
to
Chiron Paixos posted:

=If you insist on using getClass() look at the following example which
=uses a Class object to print the Class name of an object:
=
= void printClassName(Object obj) {
= System.out.println("The class of " + obj +
= " is " + obj.getClass().getName());
= }
=
=Maybe you should consider using instanceOf

How do you use <instanceOf>?

zero

unread,
Sep 29, 2005, 4:46:19 PM9/29/05
to
kvns...@hotmail.com wrote in news:1128025999.921494.219600
@g49g2000cwa.googlegroups.com:

if(obj instanceof MyClass)
System.out.println("the object is an instance of MyClass");

This won't work of course if you want the class name, in that case use
Chiron Paixos' code.

Monique Y. Mudama

unread,
Sep 29, 2005, 4:52:50 PM9/29/05
to
On 2005-09-29, kvns...@hotmail.com penned:

>
> How do you use <instanceOf>?
>
> ---Kevin Simonson

SpecialFoo myFoo = new SpecialFoo();

if (myFoo instanceof Foo)
{
doStuff();
}

--
monique

Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html

Thomas Hawtin

unread,
Sep 29, 2005, 4:51:43 PM9/29/05
to
Dave Glasser wrote:
>
> Using the == operator would probably also work:
>
> if(xyz.getClass() == Abc.class) {
> ....
>
> but I think using .equals() is safer.

Using == is the standard idiom. Using equals in this context makes the
code different and clutters. Using == also consistent with synchronising
to the class object, for instance by marking static methods with
synchronize.

Tom Hawtin
--
Unemployed English Java programmer
http://jroller.com/page/tackline/

Roedy Green

unread,
Sep 29, 2005, 4:56:56 PM9/29/05
to
On 29 Sep 2005 12:06:30 -0700, kvns...@hotmail.com wrote or quoted :

> if (xyz.getClass() == Abc)

If Abc is a class you would normally write that as:

if ( xyz instanceof Abc )

or

if ( xyz.getClass() == Abc.class )

They have slightly different meaning.

see http://mindprod.com/jgloss/classforname.html
--
Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.

kvns...@hotmail.com

unread,
Sep 29, 2005, 4:59:44 PM9/29/05
to
Thanks for all the feedback! Your answers helped a lot.

Dave Glasser

unread,
Sep 29, 2005, 5:46:20 PM9/29/05
to
Thomas Hawtin <use...@tackline.plus.com> wrote on Thu, 29 Sep 2005
21:51:43 +0100 in comp.lang.java.programmer:

>Dave Glasser wrote:
>>
>> Using the == operator would probably also work:
>>
>> if(xyz.getClass() == Abc.class) {
>> ....
>>
>> but I think using .equals() is safer.
>
>Using == is the standard idiom.

Says who?


>Using equals in this context makes the
>code different

Different? Uh, yeah, I suppose it is "different", but I'm not sure
what your point is.


> and clutters.

That's in tbe eye of the beholder. It doesn't look all that cluttered
to me, and besides, I would tend to stick with code I felt was better
rather than code that seems less cluttered.

So I guess now I should explain why I think .equals() is preferable to
== in this context. The semantics of == are clearly defined. If a and
be are object references, then "a == b" is true iff both a and b refer
to the same physical object (or instance). So, given this:

String a = new String("abc");
String b = new String("abc");

the expression "a == b" will evaluate to false, barring compiler
optimizations.

The .equals() method OTOH is more forgiving; Its semantics are defined
by the implementing class within certain constraints, but basically it
is used to determine whether two objects are "equivalent".

So, given this code:

Foo a = new Foo();
Foo b = new Foo();

Is a.getClass() guaranteed to always return the *same* instance of
java.lang.Class that b.getClass() returns? I suspect that it is and
does, but I'm not familiar enough with the Java standard to say for
sure. So I use .equals() instead, and I don't give it a second
thought.


>Using == also consistent with synchronising
>to the class object, for instance by marking static methods with
>synchronize.

Sorry, but you've lost me here. I don't see how the == operator has
anything at all to do with class-level synchronization.

Darryl L. Pierce

unread,
Sep 29, 2005, 6:41:08 PM9/29/05
to
kvns...@hotmail.com wrote:
<snip>

Why aren't you using the instanceof keyword to check whether it's an
instance of a specific class?

--
Darryl L. Pierce <mcpi...@gmail.com>
Homepage: http://mcpierce.multiply.com/
"Bury me next to my wife. Nothing too fancy..." - Ulysses S. Grant

Thomas Hawtin

unread,
Sep 30, 2005, 3:15:59 AM9/30/05
to
Dave Glasser wrote:
> Thomas Hawtin <use...@tackline.plus.com> wrote on Thu, 29 Sep 2005
> 21:51:43 +0100 in comp.lang.java.programmer:
>
>
>>Dave Glasser wrote:
>>
>>>Using the == operator would probably also work:
>>>
>>> if(xyz.getClass() == Abc.class) {
>>> ....
>>>
>>>but I think using .equals() is safer.
>>
>>Using == is the standard idiom.
>
>
> Says who?

Lot's of code.

To check I just ran the following over the latest Java SE 6 snapshot:

find /mnt/small/mustang/b53/ -name "*.java" -exec grep -h \\.class {} \;
| grep if

There were some clusters of using .equals(), but by far and away the
winner was ==.

>>Using equals in this context makes the
>>code different
>
>
> Different? Uh, yeah, I suppose it is "different", but I'm not sure
> what your point is.

Different from the clear, majority of code.

>>and clutters.
>
>
> That's in tbe eye of the beholder. It doesn't look all that cluttered
> to me, and besides, I would tend to stick with code I felt was better
> rather than code that seems less cluttered.

You aren't a big fan of operator overloading then? I don't understand
how there can be doubt whether using == or .equals() is cluttered,
particularly when surrounded by other parentheses.

> So I guess now I should explain why I think .equals() is preferable to
> == in this context. The semantics of == are clearly defined. If a and
> be are object references, then "a == b" is true iff both a and b refer
> to the same physical object (or instance). So, given this:
>
> String a = new String("abc");
> String b = new String("abc");
>
> the expression "a == b" will evaluate to false, barring compiler
> optimizations.

(False always, unless the compiler/runtime is very broken indeed.)

For Class, you need to understand what its identity means in order to
make proper use of the class. It is misleading to do something
explicitly with value that if it were necessary would invalidate really
standard stuff, such as synchronised static methods.

String is different. It's the normal case. You wouldn't (usually) use
the identity of a String object. For Class identity is important.

Darryl L. Pierce

unread,
Sep 30, 2005, 6:45:15 AM9/30/05
to
Thomas Hawtin wrote:
> To check I just ran the following over the latest Java SE 6 snapshot:
>
> find /mnt/small/mustang/b53/ -name "*.java" -exec grep -h \\.class {} \;
> | grep if
>
> There were some clusters of using .equals(), but by far and away the
> winner was ==.

And did you make sure to differentiate its use on primitives (for which
.equals() isn't possible) and its use on object references?

Dave Glasser

unread,
Sep 30, 2005, 9:19:10 AM9/30/05
to
Thomas Hawtin <use...@tackline.plus.com> wrote on Fri, 30 Sep 2005
08:15:59 +0100 in comp.lang.java.programmer:

>Dave Glasser wrote:
>> Thomas Hawtin <use...@tackline.plus.com> wrote on Thu, 29 Sep 2005
>> 21:51:43 +0100 in comp.lang.java.programmer:
>>
>>
>>>Dave Glasser wrote:
>>>
>>>>Using the == operator would probably also work:
>>>>
>>>> if(xyz.getClass() == Abc.class) {
>>>> ....
>>>>
>>>>but I think using .equals() is safer.
>>>
>>>Using == is the standard idiom.
>>
>>
>> Says who?
>
>Lot's of code.
>
>To check I just ran the following over the latest Java SE 6 snapshot:
>
>find /mnt/small/mustang/b53/ -name "*.java" -exec grep -h \\.class {} \;
>| grep if
>
>There were some clusters of using .equals(), but by far and away the
>winner was ==.

That still doesn't make it the "standard idiom." In fact, the fact
that the Mustang snapshot, written by the High Priests of the Java
Language, contains *both* styles indicates, if anything, that there is
no "standard idiom."


>
>>>Using equals in this context makes the
>>>code different
>>
>>
>> Different? Uh, yeah, I suppose it is "different", but I'm not sure
>> what your point is.
>
>Different from the clear, majority of code.

Uh, the Mustang snapshot in no way represents the "clear majority of
code."


>>>and clutters.
>>
>>
>> That's in tbe eye of the beholder. It doesn't look all that cluttered
>> to me, and besides, I would tend to stick with code I felt was better
>> rather than code that seems less cluttered.
>
>You aren't a big fan of operator overloading then?

No, I wouldn't call myself one.

>I don't understand
>how there can be doubt whether using == or .equals() is cluttered,
>particularly when surrounded by other parentheses.

.equals() may be *more* cluttered than ==, but it still looks
perfectly readable to me.


>
>> So I guess now I should explain why I think .equals() is preferable to
>> == in this context. The semantics of == are clearly defined. If a and
>> be are object references, then "a == b" is true iff both a and b refer
>> to the same physical object (or instance). So, given this:
>>
>> String a = new String("abc");
>> String b = new String("abc");
>>
>> the expression "a == b" will evaluate to false, barring compiler
>> optimizations.
>
>(False always, unless the compiler/runtime is very broken indeed.)

Here again, I don't know for sure, and I wouldn't make any
assumptions. I'd write my code to work the same in either case.

>
>For Class, you need to understand what its identity means in order to
>make proper use of the class. It is misleading to do something
>explicitly with value that if it were necessary would invalidate really
>standard stuff, such as synchronised static methods.

I think I see now your point about synchronization, and I don't buy
it. You're saying that:

if(a.getClass().equals(Abc.class)) {

is somehow "misleading"? Give me a break.

And for the record, I checked the Javadoc, and java.lang.Class does
not override the Object.equals() method, so it's effectively the same
as using ==. So you use your style and I'll use mine.


Mike Schilling

unread,
Sep 30, 2005, 9:24:32 PM9/30/05
to

"Dave Glasser" <dgla...@pobox.com> wrote in message
news:hjjoj15mmtp1ibti8...@4ax.com...

> kvns...@hotmail.com wrote on 29 Sep 2005 12:06:30 -0700 in
> comp.lang.java.programmer:
>
>>Below I'm including the source code for a Java application that con-
>>tains an interface <If> and two classes that implement it, <Abc> and
>><Def>. <Rndm.open> flips a coin and returns an object of class <Abc>
>>half the time and an object of class <Def> the other half of the time.
>>Then in my <main> method I call <Rndm.open> and assign its value to
>>object <xyz>. How can I tell which class <xyz> is, <Abc> or <Def>? I
>>wrote the code below to help me tell, but when I try to compile it I
>>get the error message:
>>
>> Gc.java:36: cannot find symbol
>> symbol : variable Abc
>> location: class Gc
>> if (xyz.getClass() == Abc)
>
>
> Use the class literal for Abc, which is Abc.class:
>
> if(xyz.getClass().equals(Abc.class)) {
> ...
>
> Using the == operator would probably also work:
>
> if(xyz.getClass() == Abc.class) {
> ....
>
> but I think using .equals() is safer.

They're equivalent; Class.equals() is implemented as object equality. "=="
is slightly faster, not that that's a compelling argument.


steve

unread,
Oct 8, 2005, 2:28:17 AM10/8/05
to
On Sat, 1 Oct 2005 09:24:32 +0800, Mike Schilling wrote
(in article <kzl%e.1914$Fi3...@newssvr29.news.prodigy.net>):

they are NOT the same.

== compares to see if they are the SAME OBJECT IN MEMORY
.equals() compares to see if they are the same value

try using it on a primitive or constant, then see if they are the same.
better still try comparing 2 intergers.

Mike Schilling

unread,
Oct 8, 2005, 8:24:55 AM10/8/05
to

"steve" <st...@aol.com> wrote in message
news:di7ou...@news1.newsguy.com...

They are the same for Class instances, which was the subject being
discussed.


steve

unread,
Oct 9, 2005, 5:03:50 AM10/9/05
to
On Sat, 8 Oct 2005 20:24:55 +0800, Mike Schilling wrote
(in article <rUO1f.2535$xD7...@newssvr29.news.prodigy.net>):

I ran into this in a database photo album I wrote, it was a bugger of a mess
to track down & clean up.

the default implementation of equals() in java.lang object compares objects
by identity , not by equality.

equals() and == are not the same, and it is better people learn that from the
start, instead of introducing confusion and saying :
sometimes they maybe are ,
but sometimes they are maybe not.

Anyway you are entitled to code any way you so desire as am I.


Mike Schilling

unread,
Oct 9, 2005, 4:08:06 PM10/9/05
to

"steve" <st...@aol.com> wrote in message
news:diamd...@news2.newsguy.com...

>
> equals() and == are not the same, and it is better people learn that from
> the
> start, instead of introducing confusion and saying :
> sometimes they maybe are ,
> but sometimes they are maybe not.

They are the same for Class instances, which was the subject being
discussed.


Owen Jacobson

unread,
Oct 10, 2005, 2:02:27 AM10/10/05
to

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.

Mike Schilling

unread,
Oct 10, 2005, 2:19:44 AM10/10/05
to

"Owen Jacobson" <angryb...@google-email-service.example.com> wrote in
message
news:pan.2005.10.10....@google-email-service.example.com...

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


Chris Uppal

unread,
Oct 10, 2005, 2:42:02 AM10/10/05
to
Mike Schilling wrote:

> 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


Mike Schilling

unread,
Oct 10, 2005, 3:42:11 AM10/10/05
to

"Chris Uppal" <chris...@metagnostic.REMOVE-THIS.org> wrote in message
news:434a0cbf$0$38045$bed6...@news.gradwell.net...

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!


Mark Thornton

unread,
Oct 10, 2005, 4:20:58 AM10/10/05
to

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


Owen Jacobson

unread,
Oct 10, 2005, 4:24:38 AM10/10/05
to
On Mon, 10 Oct 2005 07:42:11 +0000, Mike Schilling wrote:

> "Chris Uppal" 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.

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.

Mark Thornton

unread,
Oct 10, 2005, 4:29:00 AM10/10/05
to
Owen Jacobson wrote:
> On Mon, 10 Oct 2005 07:42:11 +0000, Mike Schilling wrote:
>
>
>>"Chris Uppal" 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.
>
>
> 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.

Owen Jacobson

unread,
Oct 10, 2005, 4:42:18 AM10/10/05
to

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

Chris Uppal

unread,
Oct 10, 2005, 4:55:08 AM10/10/05
to
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


0 new messages