instanceof NOT (always) bad? The instanceof myth.

O

Oliver Wong

Twisted said:
It probably opens them wide to all kinds of lawsuits, liability, and
antitrust actions.

It seems we're straying pretty far off topic. If you know of an
appropriate newsgroup and want to continue this discussion, let me know
where. Otherwise, I'm satisfied to leave things as they are.

- Oliver
 
D

dmx_dawg

Hi all.

I was in a bit of a 'rant' mode when I wrote that post, however I
believe the content stands (even if the tone was sometimes a bit
sarcastic). However, I'm very very pleasantly surprised to see the
great, well thought-out responses.

Chris:
I do note those who are simply 'sagely warning' about the possible
implications of the keyword, however there are those that, as you
mention, 'mechanically' abide by a 'never ever use instanceof' mantra.
For example:

Now I assume they were referring to the keyword's use in the particular
example shown as being bad design (and not in all cases), but this is
the type of things that helps start these bad practice phobias where
people forget about the context of the use and focus only on the use
itself.

A few points:

As for the isAssignable method, I agree it can be used. But it seems
to essentially do the same thing as instaceof and hence, as far as
popular 'best-practice' goes, it has all the same faults of instaceof.
eg: "Your design should be using polymorphism and have no need for
isAssignable".

As for polymorphism vs instanceof, I've always agreed with anyone who
has felt that:

1) if it can be done in a way that doesn't actually take away from
application ease-of-maintenance

2) if it can be done in a way that doesn't add too much undue
complexity

3) if it makes sense from the logical abstraction of your system

....then polymorphism is the way to go. Luckily in my experience
(although often requiring a little iteration and refactoring):
polymorphism is possible, instanceof is not required, the design ends
up cleaner and everyone is happy. Its funny you mentioned the
'dynamic' aspect of the examples I presented, as the application that
triggered my email (in which instanceof is used--sparingly) has a
plugin architecture where classes are frequently dynamically loaded.

We've also been able to reduce the use of instanceof by relying more on
plugin descriptors for information rather than determining such things
at runtime (the use of descriptors was actually always the plan). But
there are still cases where instanceof makes the most sense (or perhaps
isAssignable--I will read up on it more to see if it offers advantages
to our application over instanceof).


Anywho, thanks all for the informative posts!



Cheers!

-mike

Chris said:
I just decided to write a message regarding the myth that the use of
the instanceof keyword is categorically bad. Not all java programmers
have fallen prey to the myth, but after years on the newsgroups it has
almost gotten to the point where if it was discovered that you used
instanceof anywhere in your app, it *must* be because you have a poorly
designed system.

On these newsgroups? I've followed these newsgroups for many years
(since about 1998) and haven't gotten that impression. Nevertheless, if
the impression has been given, then it is incorrect.

What has often been said is that avoiding runtime type dependencies in
general is a good idea whenever possible. Typically, though, this
advice is applied to reflection instead of use of the instanceof
keyword. I can also see that there are a lot of places where someone
unfamiliar with OO programming may wish to use instanceof, but which
should be replaced with polymorphism. Again, though, I see no
justification for an absolute rule forbidding instanceof. Indeed,
inheritance is often poorly applied to situations where it breaks proper
separation of concerns.
It has been said that, in most cases, instanceof should not be used to
test for object equality (see [BLEWITT1]) as it can break the symmetric
property of the equals method's equivalence relation. In this case,
using the getClass method of Object is the appropriate choice. This
makes a lot of sense.

I am completely with you on this one. I have noticed a tendency (not so
much on this newsgroup, but in other places, at least, such as
introductory textbooks of fly-by-night tutorial web sites that are
sometimes posted here) to do the following:

1. Assume that the programmer intends to write a certain kind of very
mechanical implementation of the equals or hashCode methods.

2. Draw conclusions about how to uphold their contracts, on the basis of
these mechanical implementations.

3. Forget that less mechanical implementations are possible.

This tendency is exaggerated by the section (which is a good one, by the
way) in Josh Bloch's Effective Java that gives a mechanical way to
handle hashCode (but that *also* notes that it only applies to
information that is relevant to object identity... a qualification that
is often lost in translation), and by the kinds of silly introductory
examples to overriding hashCode and equals that are frequently in intro
textbooks or tutorials.

An excellent example of where this does NOT apply is java.util.List.
The contract for java.util.List.equals contains a requirement that any
List should compare equal to any other List with the same contents. I
think this is a very poor requirement, but it is nevertheless a
requirement. Beginning an implementation of MyList.equals by comparing
this.getClass() to other.getClass() is a sure-fire guarantee of breaking
the contract.

What is true, though, is that in the absence of some specification for
how to declare dissimilar classes, the task shoulod be considered
impossible... i.e., they should always be considered unequal. That
specification logically ought to occur in the documentation of some
supertype. Hence, it may be valid to say that instanceof should never
be used to check equals UNLESS there is some specification in some
supertype that defines equality for some containing inheritance sub-
hierarchy.
Another thing you may find on the net are people who will try their
darndest to provide you with an example of how you can get around using
instanceof. They will explain that you need their complex, difficult
to maintain, cyclic-dependency-creating solutions because your design
is bad (you used instanceof right?... so it *must* be bad), and that
your solution will certainly be a nightmare to maintain in the future.

Hopefully, you don't mean to include here situations in which someone
provides not only general advice on how to avoid using instanceof, but
also specific negative consequences of the use of instanceof, and how
their proposed solutions avoids those drawbacks. For example, one
common problem with instanceof is that it introduces a single point that
must be extended in order to completely integrate a new subtype into the
system. If the solution can avoid this by moving certain type-specific
code into the subclass itself, this is nearly always a good thing.
Therefore, there is reason to be cautious with this keyword when working
in a situation where the list of possible subtypes is not theoretically
limited, such as when working with a hierarchy of objects representing
different accounting policies for various legal jurisdictions.
Use method overloading instead
==============================
Visitor (and Proxy Visitor)
===========================

You missed the obvious one. If possible, take the type-specific
behavior, and move it into a polymorphic method of the class. Doing so
can require some creativity in design... but that's because you're
really doing design rather than following someone's furmulaic answer.
Design is a creative process. It involves finding and using the
abstractions that are inherent to the system.

My suspicion is that when most advice is given to avoid instanceof, this
is what is meant. Don't use instanceof, but rather identify and
describe the inherent abstractions that allow you to write something
that applies to all relevant types. If the advice is taken to mean
something else, such as that a specific trick should be employed to
remove the keyword in an automatable way, then someone has profoundly
missed the point.
Other people using instanceof
=============================

Note that most of the really good examples of using instanceof come from
writing code that is inherently somewhat dynamic systems. The only
exception I can think of comes from so-called "marker" interfaces, which
are problematic from a design standpoint anyway; or from backward-
compatibility limitations that prevent making appropriate changes to a
common supertype.
 
Joined
Jan 21, 2022
Messages
1
Reaction score
0
public void scare(Fish fish)
{
f.move();
f.eatAlgae();
}

Do you realize that the parameter name is fish, not f? Of course the code won't compile because it will 'think', "what the heck is 'f'? ERROR"! Using instanceof will not fix it; using an IDE to catch such a simple mistake will.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,920
Messages
2,570,038
Members
46,449
Latest member
onedumbsquirrel

Latest Threads

Top