From: Lew on
Lew wrote:
>> Always override 'equals()', 'hashCode()' and 'toString()' together or
>> not at all; keep them consistent with each other. If 'Foo' implements
>> 'Comparable<Foo>' then it must override those three, all consistent with
>> 'compareTo(Foo)'.

Arne Vajhøj wrote:
> There are very good reasons to override equals and hashCode together.
>
> I can see many cases where overriding toString alone makes sense,
> because its main purpose is to make developer logging easier. And
> often you will want to log something without it having to be
> comparable.

There's nothing in my advice to require loggable things to be Comparable.

If you're logging information that identifies an instance, by definition you
have to provide a string representation of the identifying attributes of the
instance. If you aren't logging an instance's identifying attributes, you
don't use 'toString()' in the log message. Ergo, 'toString()' has to include
the identifying attributes of the instance to be useful.

The identifying attributes of the instance are precisely those that figue in
to 'equals()' and 'hashCode()', with the possible addition of the object
identifier. Ergo, 'toString()' must be consistent with 'equals()' and
'hashCode()', in the sense that it must represent the values of the attributes
that figure in to those methods.

Q.E.D.

--
Lew
From: Robert Klemme on
On 31.05.2010 18:57, Tom Anderson wrote:
> On Mon, 31 May 2010, Lew wrote:
>
>> Tom Anderson wrote:
>>> if ((obj == null) || !(obj instanceof SearchResultHotels)) return false;
>>
>> The '(obj == null)' clause is superfluous.
>
> Good point.
>
> My brain, for some reason, has a hard time remembering that:
>
> SearchResultHotels x = (SearchResultHotels)null;
>
> is okay but:
>
> null instanceof SearchResultHotels
>
> is false.

You just need to remember that null does not have a type. At least
that's what helped me to get this straight. :-)

Also, "nothing" cannot really be an instance of "something", can it?

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
From: Tom Anderson on
On Mon, 31 May 2010, Robert Klemme wrote:

> On 31.05.2010 18:57, Tom Anderson wrote:
>> On Mon, 31 May 2010, Lew wrote:
>>
>>> Tom Anderson wrote:
>>>> if ((obj == null) || !(obj instanceof SearchResultHotels)) return false;
>>>
>>> The '(obj == null)' clause is superfluous.
>>
>> Good point.
>>
>> My brain, for some reason, has a hard time remembering that:
>>
>> SearchResultHotels x = (SearchResultHotels)null;
>>
>> is okay but:
>>
>> null instanceof SearchResultHotels
>>
>> is false.
>
> You just need to remember that null does not have a type. At least
> that's what helped me to get this straight. :-)

Yes, when i think about it, it's all perfectly clear. But i get it wrong
when i'm not thinking about it.

In further penance, i should point out that the instanceof test is risky
if the class can have subclasses, and where those subclasses might have
different ideas about equality. A more conservative form might be:

if ((obj == null) || !(obj,getClass().equals(SearchResultHotels.class)) return false;

> Also, "nothing" cannot really be an instance of "something", can it?

Ah, but you would agree that nothing can be an instance of everything!

tom

--
Judge Dredd. Found dead. Face down in Snoopy's bed.
From: Mike Schilling on
Tom Anderson wrote:
> On Mon, 31 May 2010, Robert Klemme wrote:
>
>> On 31.05.2010 18:57, Tom Anderson wrote:
>>> On Mon, 31 May 2010, Lew wrote:
>>>
>>>> Tom Anderson wrote:
>>>>> if ((obj == null) || !(obj instanceof SearchResultHotels)) return
>>>>> false;
>>>>
>>>> The '(obj == null)' clause is superfluous.
>>>
>>> Good point.
>>>
>>> My brain, for some reason, has a hard time remembering that:
>>>
>>> SearchResultHotels x = (SearchResultHotels)null;
>>>
>>> is okay but:
>>>
>>> null instanceof SearchResultHotels
>>>
>>> is false.
>>
>> You just need to remember that null does not have a type. At least
>> that's what helped me to get this straight. :-)
>
> Yes, when i think about it, it's all perfectly clear. But i get it
> wrong when i'm not thinking about it.

Me too. Especially since the usage

if (x instanceof Type)
{
Type t = (Type)x;
...

is so common. The instanceof check (among other things) avoids a cast
failure, but the cast would work perfectly well if x were null.


From: markspace on
Tom Anderson wrote:

> Ah, but you would agree that nothing can be an instance of everything!


No, but I'd agree that a reference can point to nothing. ;-)