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_
>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)
>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.
If you're a musician, check out RPitch Relative Pitch
Ear Training Software.
=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>?
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.
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
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/
> 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.
>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.
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
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.
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 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.
They're equivalent; Class.equals() is implemented as object equality. "=="
is slightly faster, not that that's a compelling argument.
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.
They are the same for Class instances, which was the subject being
discussed.
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.
>
> 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.
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.
> 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
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!
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
> "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.
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
> 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