Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Casting an object in equals Java 5

Reply
Thread Tools

Casting an object in equals Java 5

 
 
crazzybugger
Guest
Posts: n/a
 
      09-30-2008
Hi,
I am stuck with a compiler warning while trying to cast an
object inside equals method.
Consider class A<I>{ }
inside this class, I am trying to override equals method. However, I
am not able to cast the received object into the proper type without
compiler warning.

Consider this implementation of equals
public boolean equals(Object that){
if(that instanceof A){
A<I> that1 = this.getClass().cast(that); // here I am
getting compiler warning.
// perform comparisons...
}
}

what is the right way to cast here ?
thank you...
 
Reply With Quote
 
 
 
 
crazzybugger
Guest
Posts: n/a
 
      09-30-2008
On Sep 30, 1:25*pm, Sabine Dinis Blochberger <(E-Mail Removed)>
wrote:
> crazzybugger wrote:
> > Hi,
> > * * * I am stuck with a compiler warning while trying to cast an
> > object inside equals method.
> > Consider class A<I>{ }
> > inside this class, I am trying to override equals method. However, I
> > am not able to cast the received object into the proper type without
> > compiler warning.

>
> > Consider this implementation of equals
> > public boolean equals(Object that){
> > * * *if(that instanceof A){
> > * * * * *A<I> that1 = this.getClass().cast(that); * // here I am
> > getting compiler warning.
> > * * * * // perform comparisons...
> > * * }
> > }

>
> > what is the right way to cast here ?
> > thank you...

>
> Since you already test if "that" is an instance of "A", do you even need
> to cast it (assuming "A" is the class that implements this "equals()")?
>
> A cast only tells the compiler to pretend/handle it as if that this
> object is of type X, it does not convert the object in any way.
>
> <http://mindprod.com/jgloss/cast.html>


If I donot cast it as an object of A<I> how can I access the methods &
attributes of A ? Besides If I try casting it as object of type 'A'
and not as A<I>, I get the 'not parameterised' warning!!!
 
Reply With Quote
 
 
 
 
Andreas Leitgeb
Guest
Posts: n/a
 
      09-30-2008
crazzybugger <(E-Mail Removed)> wrote:
> Consider class A<I>{ }
> public boolean equals(Object that){
> if(that instanceof A){
> A<I> that1 = this.getClass().cast(that); // here I am getting compiler warning.


Casting from Object to a parameterized type is fragile, because
not even at runtime can it be verified that the complete type
is correct. You can always cast to "A": A that1 = (A)that;
Sometimes that may be enough to determine equality.

If you look at how Sun did it, e.g. in AbstractMap<K,V>, then
you'll see that they simply did it analogously to

A<I> that1 = (A<I>) that;

and either ignored or suppressed the resulting warning.

PS: I think, that "normal" programs should never have a need
for .getClass(). (Application servers are not "normal" and
neither are class viewers in this context

 
Reply With Quote
 
RedGrittyBrick
Guest
Posts: n/a
 
      09-30-2008

crazzybugger wrote:
> On Sep 30, 1:25 pm, Sabine Dinis Blochberger <(E-Mail Removed)>
> wrote:
>> crazzybugger wrote:
>>> Hi,
>>> I am stuck with a compiler warning while trying to cast an
>>> object inside equals method.
>>> Consider class A<I>{ }
>>> inside this class, I am trying to override equals method. However, I
>>> am not able to cast the received object into the proper type without
>>> compiler warning.
>>> Consider this implementation of equals
>>> public boolean equals(Object that){
>>> if(that instanceof A){
>>> A<I> that1 = this.getClass().cast(that); // here I am
>>> getting compiler warning.
>>> // perform comparisons...
>>> }
>>> }
>>> what is the right way to cast here ?
>>> thank you...

>> Since you already test if "that" is an instance of "A", do you even need
>> to cast it (assuming "A" is the class that implements this "equals()")?
>>
>> A cast only tells the compiler to pretend/handle it as if that this
>> object is of type X, it does not convert the object in any way.
>>
>> <http://mindprod.com/jgloss/cast.html>

>
> If I donot cast it as an object of A<I> how can I access the methods &
> attributes of A ?


You can't. But I don't understand your "this.getClass().cast(that);"
I'd try

A<I> that1 = (A<I>) that;
that1.methodOfA();


By the way, your choice of example variable names confuses me. I'd maybe
have chosen them like this ...

public boolean equals(Object object) {
if (object instanceof A) {
A<I> a = (A<I>) object;
...


> Besides If I try casting it as object of type 'A'
> and not as A<I>, I get the 'not parameterised' warning!!!


Which is as it should be, why would you expect anything else?


--
RGB
 
Reply With Quote
 
Roland de Ruiter
Guest
Posts: n/a
 
      09-30-2008
On 30-9-2008 9:40, crazzybugger wrote:
> Hi,
> I am stuck with a compiler warning while trying to cast an
> object inside equals method.
> Consider class A<I>{ }
> inside this class, I am trying to override equals method. However, I
> am not able to cast the received object into the proper type without
> compiler warning.
>
> Consider this implementation of equals
> public boolean equals(Object that){
> if(that instanceof A){
> A<I> that1 = this.getClass().cast(that); // here I am
> getting compiler warning.
> // perform comparisons...
> }
> }
>
> what is the right way to cast here ?
> thank you...


if (that instanceof A) {
A<?> that1 = (A<?>)that;
...
}

The actual type parameter of "that" isn't known at runtime, so you can
only cast it safely to an A of unknown type, i.e. A<?>.

I wouldn't use getClass().cast() if A can have subclasses, let's say B
and C, because this cast will fail if "this" is an instance of B and
"that" is an instance of C.
--
Regards,

Roland
 
Reply With Quote
 
Andreas Leitgeb
Guest
Posts: n/a
 
      10-01-2008
Eric Sosman <(E-Mail Removed)> wrote:
> Andreas Leitgeb wrote:
>> PS: I think, that "normal" programs should never have a need
>> for .getClass(). (Application servers are not "normal" and
>> neither are class viewers in this context

>
> One of the few places where .getClass() seems essential is in
> implementing .equals() for non-final classes:


In my Java classes they told me not to do that at all.
Either make these classes (or equals() itself, along with
hashCode()) final or abstract.

Btw., I think that class-equality is not a necessary
condition for a contract-fulfilling (and non-trivial)
equals(). It's quite feasible, that a subclass, while
adding new fields and stuff, still adheres to the base-
class' definition of equality. Proper implementation
of this behaviour would have final equals() & hashCode()
in the non-final baseclass.

Apart from that case there is the situation that one should
either avoid entirely, or solve with reflection (and getClass()
is kind of an entry-point of reflection).

Any examples of where such a class-hierarchy with non-leaf
classes having to be non-abstract really and inevitably
comes up? (I'd like to know. I don't deny the possibility)

> class Super {
> public boolean equals(Object obj) {
> if (obj.getClass() != Super.class) return false;


If it were really necessary, I'd probably rather do it
as: if (obj.getClass() != getClass()) return false;
to also deal with classes that do not override equals()
but still want their instances to be able to equal other
instances of the same subclass, or even themselves, based
only on baseclass features.

> Does anyone know of a smoother way to do this?

Yes: avoid the situation

Make all leaf-classes final, and all others abstract.
OR: Allow subhierarchies where subclass instances can legally
equal instances of any other class within that subhierarchy.

 
Reply With Quote
 
Andreas Leitgeb
Guest
Posts: n/a
 
      10-01-2008
Andreas Leitgeb <(E-Mail Removed)> wrote:
> Eric Sosman <(E-Mail Removed)> wrote:
>> class Super {
>> public boolean equals(Object obj) {
>> if (obj.getClass() != Super.class) return false;


Another caveat with this approach:
if some subclass's equals() calls super.equals(), it may
get (unexpected) wrong negatives, even for identical
objects...

 
Reply With Quote
 
Patricia Shanahan
Guest
Posts: n/a
 
      10-01-2008
Andreas Leitgeb wrote:
> Eric Sosman <(E-Mail Removed)> wrote:
>> Andreas Leitgeb wrote:
>>> PS: I think, that "normal" programs should never have a need
>>> for .getClass(). (Application servers are not "normal" and
>>> neither are class viewers in this context

>> One of the few places where .getClass() seems essential is in
>> implementing .equals() for non-final classes:

>
> In my Java classes they told me not to do that at all.
> Either make these classes (or equals() itself, along with
> hashCode()) final or abstract.

....

I take a rather different position. If a non-final class overrides
equals and hashCode, its documentation should include rules for subclass
equality.

Treating an object as being unequal from instances of its class's
subclasses is one possible rule, but not the only one.

For example, the List interface has a set of rules for equals and
hashCode that allow equality comparison of any two instances of any
class implementing List, regardless of whether the two objects are of
the same class or not.

AbstractList implements those rules using only the methods any List
implementation must have.

Patricia
 
Reply With Quote
 
Andreas Leitgeb
Guest
Posts: n/a
 
      10-01-2008
Eric Sosman <(E-Mail Removed)> wrote:
> Andreas Leitgeb wrote:
>> In my Java classes they told me not to do that at all.
>> Either make these classes (or equals() itself, along with
>> hashCode()) final or abstract.


> Maybe I've misunderstood, but this seems crazy.


In that class we had our "hands-on" example, some class
describing a (3D-)Point, and it had an equals() that compared
all three coordinates, and a hashCode() that was consistent
with equals().

Then the instructor raised the point of deriving a "ColoredPoint"
and showed us the bad effect of the naive approach for overriding
equals (and hashCode()) in ColoredPoint.

Generally (my own words):
One can only weaken(**) the equality relation when deriving
instanciable classes from other instanciable classes.
Otherwise, it results in an asymmetric (thus broken)
relation. (**): i.e.: grow the equivalence classes

But in subhierarchies, one generally wants to make the
subclasses equality more fine-grained. That's the problem.

The solutions for this problem are these:

- Document some appropriate contract for all subclasses

- Only care about leaf-classes' equals(). Let non-leaf
classes inherit Object's equals() or make them
abstract.

- Prevent subclassing (make the class final).

- Just prevent subclasses from fiddling with .equals()
or hashCode() (make these methods final)

- Make the baseclass's .equals() artificially more finegrained,
by growing only those equivalence classes that only
contain direct baseclass-instances.
This requires using getClass(), and the result is, that
any subclass cannot tell it apart from Object.equals().

While technically ok and legal, it (imho) contradicts
OO-principles, just like having any other method that does
something useful for instances of the class it's defined
in, but does nothing for any subclass-instance. brrr.

Those who use getClass() for equals() probably also torture
baby dogs in their leisure time

 
Reply With Quote
 
Andreas Leitgeb
Guest
Posts: n/a
 
      10-01-2008
Lew <(E-Mail Removed)> wrote:
> He [Bloch] does recommend to "Design and document for inheritance or
> else prohibit it" (Item 17), which Andreas's instructors might have twisted.


Don't attribute to my instructor's what you can attribute to me

I was just omitting the omnipresent principle of that my class can
have any cruel behaviour, that may require the user/subclasser to
jump through hoops, as long as I document each and every such hoop.

With that implicit alternative it's pretty well the same as how
I understood Bloch.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How does equals method work on a String Buffer object! javabeginner29 Java 0 04-02-2012 10:14 AM
Up casting and down casting Sosuke C++ 2 12-20-2009 03:24 PM
Problem with depracated casting method (down casting) Wally Barnes C++ 3 11-20-2008 05:33 AM
Another question about inheritance (up-casting and down-casting) kevin Java 11 01-08-2005 07:11 PM
does String.equals breaks the equals contract? Edward A Thompson Java 4 02-11-2004 11:33 PM



Advertisments