Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Is instanceof dirty?

Reply
Thread Tools

Is instanceof dirty?

 
 
DeMarcus
Guest
Posts: n/a
 
      11-08-2004

Hi,

I come from the C++ world and there they say "no no" when
you want to switch on type information. Even the inventor
of C++ say so.

What's the common opinion about using the java keyword
instanceof?


// Daniel


 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      11-08-2004
DeMarcus wrote:
> Hi,
>
> I come from the C++ world and there they say "no no" when
> you want to switch on type information. Even the inventor
> of C++ say so.
>
> What's the common opinion about using the java keyword
> instanceof?


Use it when you must. For example, in

class Thing {
public boolean equals(Thing other) {
return ...something...;
}

public boolean equals(Object other) {
return other instanceof Thing
&& equals((Thing)other);
}
}

the `instanceof' seems perfectly normal (and vastly
preferable to catching a ClassCastException). On the
other hand, if you find code like

if (ref instanceof Thing)
...
else if (ref instanceof Ding)
...
else if (ref instanceof Cosa)
...
else
throw new ResException(...);

.... it's probably time to re-think the design.

--
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
 
 
 
Chris Smith
Guest
Posts: n/a
 
      11-08-2004
DeMarcus wrote:
> I come from the C++ world and there they say "no no" when
> you want to switch on type information. Even the inventor
> of C++ say so.
>
> What's the common opinion about using the java keyword
> instanceof?


Pretty much the same.

Nevertheless, a lot more dynamic code gets written in Java than in C++,
including stuff with on-the-fly classloaders, mobile code, etc. As a
result, the need for instanceof can become apparent. For example, say
you've developed a plugin architecture based on bytecode, but you need
to ensure that the class the user provides actually implements the
correct interface. This is a case where the traditional disadvantages
of runtime type comparisons are moot, and performing the type check at
runtime is a very good idea.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
Reply With Quote
 
Stefan Schulz
Guest
Posts: n/a
 
      11-08-2004
On Mon, 08 Nov 2004 13:20:00 -0500, Eric Sosman <(E-Mail Removed)>
wrote:

>
> the `instanceof' seems perfectly normal (and vastly
> preferable to catching a ClassCastException). On the
> other hand, if you find code like
>
> if (ref instanceof Thing)
> ...
> else if (ref instanceof Ding)
> ...
> else if (ref instanceof Cosa)
> ...
> else
> throw new ResException(...);
>
> ... it's probably time to re-think the design.


I would not be so strict... i would allow code like

if (ref instanceof GoodBoy)
// do quick and efficiant algorithm only applicable for goodboys
else
// do long and complicated algorithm that works in the general case

A good example of this kind of thinking would be the java.util.RandomAccess
interface.



--

Whom the gods wish to destroy they first call promising.
 
Reply With Quote
 
Stefan Schulz
Guest
Posts: n/a
 
      11-08-2004
On Mon, 08 Nov 2004 18:04:14 GMT, DeMarcus <(E-Mail Removed)> wrote:

>
> Hi,
>
> I come from the C++ world and there they say "no no" when
> you want to switch on type information. Even the inventor
> of C++ say so.
>
> What's the common opinion about using the java keyword
> instanceof?


Try not to use it when other information will do, it is easy
to make mistakes. But it is a useful capability when used in
moderation.

Just my .02$
Stefan

--

Whom the gods wish to destroy they first call promising.
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      11-08-2004
Stefan Schulz wrote:
> On Mon, 08 Nov 2004 13:20:00 -0500, Eric Sosman <(E-Mail Removed)>
> wrote:
>
>
>>the `instanceof' seems perfectly normal (and vastly
>>preferable to catching a ClassCastException). On the
>>other hand, if you find code like
>>
>> if (ref instanceof Thing)
>> ...
>> else if (ref instanceof Ding)
>> ...
>> else if (ref instanceof Cosa)
>> ...
>> else
>> throw new ResException(...);
>>
>>... it's probably time to re-think the design.

>
>
> I would not be so strict... i would allow code like
>
> if (ref instanceof GoodBoy)
> // do quick and efficiant algorithm only applicable for goodboys
> else
> // do long and complicated algorithm that works in the general case
>
> A good example of this kind of thinking would be the java.util.RandomAccess
> interface.


"Re-think" is not a synonym for "reject." Re-thinking
the design might lead to the conclusion that nothing should
change, despite appearances. Or, as they say in American
football, "Upon further review, the play stands as called."

With that understood, I'll stand by my opinion (which
I don't think is "strict" at all): Code liberally sprinkled
with `instanceof' operators ought to be re-thought -- but
not necessarily re-written.

--
(E-Mail Removed)

 
Reply With Quote
 
Daniel Grieves
Guest
Posts: n/a
 
      11-08-2004
I would disagree with this statement under certain circumstances,
specifically if your design contract for a method specifies that an incoming
variable be of a certain type. For example, I'm a big fan of the old JGL
library (I dunno, I just got hooked on it and never switched over to the
new, templatized Java collection classes). If for example I declare a
method that takes a parameter of type Array, and I specify in the contract
for that method that the Array will contain only objects of type String,
then I would not feel bad about casting blindly and catching (or throwing)
the ClassCastException.

Dan

"Eric Sosman" <(E-Mail Removed)> wrote in message
news:cmodch$dpv$(E-Mail Removed)...
> the `instanceof' seems perfectly normal (and vastly
> preferable to catching a ClassCastException).



 
Reply With Quote
 
Andrea Desole
Guest
Posts: n/a
 
      11-09-2004
If you are using instanceof you are making a distinction based on the
type of the class you are referring to. Usually you would get a better
result (in the sense of better code) if you found a way to use
polymorphism, which is usually possible. In this way you make a
distinction based not on the type, but on the logic that the class shows.
Also, in the case of C++, I remember that turning on RTTI implies a
performance penalty. Apparently this is not the same in Java, according
to this article

http://www.javaworld.com/javaworld/j...2-jperf_p.html

DeMarcus wrote:
>
> Hi,
>
> I come from the C++ world and there they say "no no" when
> you want to switch on type information. Even the inventor
> of C++ say so.
>
> What's the common opinion about using the java keyword
> instanceof?
>
>
> // Daniel
>
>

 
Reply With Quote
 
Chris Uppal
Guest
Posts: n/a
 
      11-09-2004
DeMarcus wrote:

> What's the common opinion about using the java keyword
> instanceof?


I don't disagree with the previous replies that I've seen, but I wanted to give
a slightly different spin to the answer.

Think of it this way: the system (Java's semantics and OO in general) is
designed so that objects are responsible for their own behaviour. That's to
say that it's /their/ responsibility to know "what they are" and what they
should do in any specific circumstance. If you use instanceof then you are
cutting them out of the loop. In effect you are saying, "no, I don't care what
you think, I'm going to do this /my/ way".

Now that's fine if you know what you are doing and have a good reason. But you
are also throwing away the modularity, flexibility, comprehensibility, and
maintainability that were the point of using OO in the first place.

You can think of 'instanceof' as a specific kind of reflection. Other examples
of reflection are the facilities in java.lang.reflect for looking at what
methods and fields are available, and the use of finalize() to reflect on an
object's lifetime. These features allow you more power and control over the
way the system works, but at the cost that /you/ have taken over responsibility
for some aspect of the operation that the system would otherwise look after for
you. Reflection in general is something that "ordinary" programs don't, and
shouldn't, make much use of. (Although, as Chris Smith noted, it does depend
on how dynamic a programming environment / language you are working with[*])
In general, even if you do need to use reflection (and 'instanceof'
specifically) to make some design work, then it won't be as ad-hoc hacks
scattered randomly around the system. You'd be able to look at the design in
advance and say (after some thought) "we'll need to use reflection <here> and
<here>, there's no need for it anywhere else".

And I think that's the point: if you are just scattering 'instanceof' around in
an arbitrary way (if a reader can't look at what a method does and reliably
guess whether you'd use 'instanceof' before reading your code) then you are
almost certainly creating an ugly mess of hacks.

BTW, there's nothing /inherently/ wrong with slimy hacks. Sometimes you can
use a well-placed hack to gather all the ugliness of (part of) a system into
one place and hide it where it doesn't affect everything else. You'll be able
to recognise such uses quite easily since there will be a long comment
apologising for the hack, and explaining why it's better than the alternatives
in this case.

([*] E.g. I don't think I've ever used RTTI in C++ (a desperately static
environment), I can't have used 'instanceof' more than twice in Java (also
desperately static), yet I must have used it about 100 times in Smalltalk where
I can program in a /much/ more dynamic style.)

-- chris



 
Reply With Quote
 
xarax
Guest
Posts: n/a
 
      11-09-2004
"Chris Uppal" <(E-Mail Removed)-THIS.org> wrote in message
news:(E-Mail Removed)...
> DeMarcus wrote:
>
> > What's the common opinion about using the java keyword
> > instanceof?

>
> I don't disagree with the previous replies that I've seen, but I wanted to

give
> a slightly different spin to the answer.
>
> Think of it this way: the system (Java's semantics and OO in general) is
> designed so that objects are responsible for their own behaviour. That's to
> say that it's /their/ responsibility to know "what they are" and what they
> should do in any specific circumstance. If you use instanceof then you are
> cutting them out of the loop. In effect you are saying, "no, I don't care

what
> you think, I'm going to do this /my/ way".
>
> Now that's fine if you know what you are doing and have a good reason. But

you
> are also throwing away the modularity, flexibility, comprehensibility, and
> maintainability that were the point of using OO in the first place.
>
> You can think of 'instanceof' as a specific kind of reflection. Other

examples
> of reflection are the facilities in java.lang.reflect for looking at what
> methods and fields are available, and the use of finalize() to reflect on an
> object's lifetime. These features allow you more power and control over the
> way the system works, but at the cost that /you/ have taken over

responsibility
> for some aspect of the operation that the system would otherwise look after

for
> you. Reflection in general is something that "ordinary" programs don't, and
> shouldn't, make much use of. (Although, as Chris Smith noted, it does depend
> on how dynamic a programming environment / language you are working with[*])
> In general, even if you do need to use reflection (and 'instanceof'
> specifically) to make some design work, then it won't be as ad-hoc hacks
> scattered randomly around the system. You'd be able to look at the design in
> advance and say (after some thought) "we'll need to use reflection <here> and
> <here>, there's no need for it anywhere else".
>
> And I think that's the point: if you are just scattering 'instanceof' around

in
> an arbitrary way (if a reader can't look at what a method does and reliably
> guess whether you'd use 'instanceof' before reading your code) then you are
> almost certainly creating an ugly mess of hacks.
>
> BTW, there's nothing /inherently/ wrong with slimy hacks. Sometimes you can
> use a well-placed hack to gather all the ugliness of (part of) a system into
> one place and hide it where it doesn't affect everything else. You'll be able
> to recognise such uses quite easily since there will be a long comment
> apologising for the hack, and explaining why it's better than the alternatives
> in this case.

/snip/

I agree. Using "instanceof" is similar to using a switch block
with some kind of "type code" thing that distinguishes the actual
type. The general rule of OOP is that such constructs should be
replaced with polymorphism where possible. In the case of external
non-OO data, a switch block is necessary for creating the initial
object with an appropriate subtype.

I've used "instanceof" mostly in places where I was too lazy
to do it the right way. For example, an ArrayList that has both
JPanel and JLabel instances, I would use "instanceof" to distinguish
and downcast the next instance that I pulled from the ArrayList. It
was simple, it worked, and the ArrayList was very private. There was
no way that the "instanceof" usage could spread through-out the
application.


For a more flexible approach, I use something like this:
=========================================
public class Fubar
{
public void doGork(final Gork gork)
{
/* I want to do something with a Gork
that depends on the actual subtype
of Gork. */
gork.invoke(this);
}

public void doSomething(final Snafu snafu)
{
/* Snafu is a subtype of Gork. */
}


public void doSomething(final Gecko gecko)
{
/* Gecko is a subtype of Gork. */
}
}

public abstract class Gork
{
public abstract void invoke(Fubar fubar);
}

public class Snafu
extends Gork
{
public void invoke(final Fubar fubar)
{
/* calls Fubar.doSomething(Snafu) */
fubar.doSomething(this);
}
}


public class Gecko
extends Gork
{
public void invoke(final Fubar fubar)
{
/* calls Fubar.doSomething(Gecko) */
fubar.doSomething(this);
}
}
=========================================

This is a form of reflection that uses
overloading to distinguish the actual
subtype of Gork that was passed to
Fubar.doGork(Gork).

Since Fubar must know all of the subtypes of
Gorko (which it must know anyway when using
instanceof), this technique avoids instanceof
and achieves the same effect of distinguishing
the actual subtype of Gork on behalf of
Fubar.doGork(Gork).

A little imagination can extend this technique
to many subtypes of Gork by just adding the
appropriate overloaded "doSomething" method to
Fubar, and defining the new subtype of Gork with
the "invoke(Fubar)" method.

Notice that even though the "invoke" methods in
each of the subclasses are textually the same, their
effect is very different from each due to the usage
of "this" in the method call, which distinguishes
which overloaded "doSomething" method is called. You
would not want to refactor these methods to the parent
abstract class (do you see why?).

This is a very clean usage of polymorphism that
avoids "instanceof" and clearly separates the
work that Fubar.doGork(Gork) wants to perform on
the actual subtype of Gork.


--
----------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS for FREE!



 
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
instanceof NOT (always) bad? The instanceof myth. dmx_dawg@hotmail.com Java 21 07-20-2006 07:06 PM
valid use of instanceof or a better way? VisionSet Java 13 11-18-2003 10:08 PM
if (obj instanceof classVariable) ? natG Java 8 09-23-2003 07:12 PM
when to use instanceof? Digital Puer Java 3 09-05-2003 12:47 AM
Re: Dumb instanceof question Paul Tomblin Java 35 07-27-2003 07:31 PM



Advertisments