Is instanceof dirty?

Discussion in 'Java' started by DeMarcus, Nov 8, 2004.

  1. DeMarcus

    DeMarcus Guest

    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
    DeMarcus, Nov 8, 2004
    #1
    1. Advertising

  2. DeMarcus

    Eric Sosman Guest

    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.

    --
    Eric Sosman, Nov 8, 2004
    #2
    1. Advertising

  3. DeMarcus

    Chris Smith Guest

    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
    Chris Smith, Nov 8, 2004
    #3
  4. On Mon, 08 Nov 2004 13:20:00 -0500, Eric Sosman <>
    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.
    Stefan Schulz, Nov 8, 2004
    #4
  5. On Mon, 08 Nov 2004 18:04:14 GMT, 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?


    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.
    Stefan Schulz, Nov 8, 2004
    #5
  6. DeMarcus

    Eric Sosman Guest

    Stefan Schulz wrote:
    > On Mon, 08 Nov 2004 13:20:00 -0500, Eric Sosman <>
    > 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.

    --
    Eric Sosman, Nov 8, 2004
    #6
  7. 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" <> wrote in message
    news:cmodch$dpv$...
    > the `instanceof' seems perfectly normal (and vastly
    > preferable to catching a ClassCastException).
    Daniel Grieves, Nov 8, 2004
    #7
  8. 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/jw-02-1998/jw-02-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
    >
    >
    Andrea Desole, Nov 9, 2004
    #8
  9. DeMarcus

    Chris Uppal Guest

    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
    Chris Uppal, Nov 9, 2004
    #9
  10. DeMarcus

    xarax Guest

    "Chris Uppal" <-THIS.org> wrote in message
    news:...
    > 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!
    xarax, Nov 9, 2004
    #10
  11. DeMarcus <> wrote in message news:<yyOjd.8230$>...
    > 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?


    While I basicly agree with the other posts I think there are cases
    when instanceof is unavoidable. One good example is you want traverse
    a tree and want to perform different operations depending on the type
    of node you encounter. One might argue that the visitor pattern should
    be used in this case, but that requires that support for the visitor
    pattern has been implemented in the node class structure. You can't
    extend an existing class structure with the visitor pattern. Even if
    the visitor pattern has been implemented it's very awkward and
    inflexible solution that don't allow arbitrary arguments to be passed.
    The cleanest solution, which unfortunately is impossible to implement
    in Java, is multi-methods like those found in Nice,
    http://nice.sourceforge.net/visitor.html. In Java your best option is
    to use lots of "if (node instanceof X)" statements. Or you can use a
    Map<Class, Runnable> solution. Both are solutions are sub-optimal.

    /Jesper Nordenberg
    Jesper Nordenberg, Nov 9, 2004
    #11
  12. Chris Uppal wrote:

    > 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.


    The one place where I find myself frequently using instanceof in Java is
    in equals() methods, where it is common that I want to determine whether
    the object to compare to is an instance of the class to which the method
    belongs (so as to perform a comparison appropriate for that class, or
    return false if that's not possible). That particular kind of use
    doesn't seem to quite to square with your characterization (above)
    because the question isn't really a generic "what class are you?" but
    rather "is your class compatible with mine?". Would you agree that that
    kind of use makes more sense in your worldview? Do you have a preferred
    idiom to suggest?


    John Bollinger
    John C. Bollinger, Nov 9, 2004
    #12
  13. On Mon, 08 Nov 2004 18:04:14 GMT, DeMarcus <> wrote:

    >
    >Hi,
    >
    >I come from the C++ world and there they say "no no" when
    >you want to switch on type information.


    Where did you get that idea? Many dynamic object creation problems
    can require code to deliberately switch on object types.

    >Even the inventor of C++ say so.


    Stroustrap has never said "don't do it" - rather he has repeatedly
    said that RTTI is a powerful mechanism that should be used
    responsibly. C++ code that explicitly uses run time type information
    is generally not portable and requires above average attention to
    detail.

    RTTI query support was left implementation specific in the first
    versions of the C++ language standard (I don't have the latest version
    available to check if it is still the case). Stroustrap's early books
    on C++ include examples using the standard cast operators to construct
    an ad-hoc type query mechanism for cases where native compiler RTTI
    query support was not available.


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


    The functionality would not have been provided if Java's designers
    didn't think it was needed. In contrast to the C++ crowd, they were
    nice enough to provide a standard way to query RTTI from the start.

    Using "instanceof" in Java is a perfectly acceptible way to write code
    that must manipulate versioned interfaces (just as the equivalent code
    would be in C++). Others have mentioned alternate good uses for it as
    well.


    George

    --
    for email reply remove "/" from address
    George Neuner, Nov 9, 2004
    #13
  14. It's called the visitor pattern.

    /Jesper Nordenberg
    Jesper Nordenberg, Nov 10, 2004
    #14
  15. DeMarcus

    Chris Uppal Guest

    Jesper Nordenberg wrote:
    > It's called the visitor pattern.


    Or double-dispatch.

    -- chris
    Chris Uppal, Nov 10, 2004
    #15
  16. DeMarcus

    Chris Uppal Guest

    John C. Bollinger wrote:

    > The one place where I find myself frequently using instanceof in Java is
    > in equals() methods,

    [...]
    > That particular kind of use
    > doesn't seem to quite to square with your characterization (above)
    > because the question isn't really a generic "what class are you?" but
    > rather "is your class compatible with mine?". Would you agree that that
    > kind of use makes more sense in your worldview?


    Yes, I'd forgotten about that case. Thanks for the reminder. It does indeed
    make more sense.

    But equals() is such a very odd method. That's to say, the concept of
    "equality" as used in programming is so very odd -- I don't think there's
    anything specifically odd about the Java equals() method.

    It /looks/ innocous enough, but it's really very strange.

    For one thing it applies between all pairs of objects, no matter how unrelated
    they are (which, basically, is why you need the instanceof test, or an
    equivalent). Normally it would be seen as a congitive error (category error)
    to try to compare, say, an IncomeTaxBand with an IncomeTaxReturn, let alone
    with an AbstractRenderable, but equals() is expected to be up to the task...

    And then too, it's context independent, but for real purposes comparison
    /isn't/ independent of the context. You are normally wanting to know if two
    things are "the same" /for some purpose/, yet there's no mention of the context
    in equals().

    There's something twisted about the object-modelling involved in equals(). I'm
    almost tempted to say that it shouldn't exist at all. It's certainly very
    ungainly.


    > Do you have a preferred idiom to suggest?


    Not really.

    Actually, I /think/[*] I prefer to express the class-test in equals() as:

    this.getClass() == anObject.getClass()

    rather than hardwiring a reference to "my" class into the code (and that also
    avoids the potential problem, or at least ambiguity, with subclasses). But it
    comes down to pretty-much the same thing.

    ([*] I can't remember ever implementing equals() in Java, which may be
    significant in itself -- or maybe I'm just in denial ;-)

    There's an idiom (widely used in the Smalltalk class hierarchy, for instance)
    which is slightly more flexible than the class-test. I'm not sure I like it
    myself -- it doesn't really cure the equals() problems, although it does help.
    The idiom is that an object has a 'species' which is normally its own class,
    but may be some other class (usually a superclass), and the equals() method can
    compare species rather than classes:

    return this.getSpecies() == anObject.getSpecies()
    && // ... rest of comparison

    The idea is that it is testing /type/ not class, and doing so idiomatically by
    nominating (slightly arbitrarily) a specific class which is then taken to
    exemplify the type shared by a whole category of concrete classes. "Paradigm"
    would be a better name than "species", but unfortunately that word has been
    hijacked by bloody Kuehn (sp?) and I don't think many people would recognise it
    in the correct/original sense of "defining example".

    It's not something you could use directly in Java, since that would require
    getSpecies() to be defined by java.lang.Object, though you could use instanceof
    to emulate it. An elegant variant would be to use an interface as the
    nominated (paradigmatic) class. Come to think of it, maybe that's how you
    /are/ using instanceof in your applications ?

    -- chris
    Chris Uppal, Nov 10, 2004
    #16
  17. On Wed, 10 Nov 2004 11:07:16 -0000, Chris Uppal
    <-THIS.org> wrote:

    > John C. Bollinger wrote:
    >
    >> The one place where I find myself frequently using instanceof in Java is
    >> in equals() methods,

    > [...]
    > Actually, I /think/[*] I prefer to express the class-test in equals() as:
    >
    > this.getClass() == anObject.getClass()
    >
    > rather than hardwiring a reference to "my" class into the code (and that
    > also
    > avoids the potential problem, or at least ambiguity, with subclasses).
    > But it
    > comes down to pretty-much the same thing.
    >
    > ([*] I can't remember ever implementing equals() in Java, which may be
    > significant in itself -- or maybe I'm just in denial ;-)


    This will fail if you get an Object of a subclass of your own... one you
    could
    compare (and which would be an instanceof your class=


    --

    Whom the gods wish to destroy they first call promising.
    Stefan Schulz, Nov 10, 2004
    #17
  18. DeMarcus

    Chris Uppal Guest

    Stefan Schulz wrote:

    > > this.getClass() == anObject.getClass()


    > This will fail if you get an Object of a subclass of your own... one you
    > could
    > compare (and which would be an instanceof your class=


    Well, that's my point isn't it -- or part of my point anyway ? Whether, and
    why, an object could be considered to be equal() to an instance of a subclass
    of its own class is not well-defined. Maybe it should, maybe it shouldn't.
    It's probably context dependent. It's certainly application dependent. But I
    think it's worse than that:

    Consider two classes Super and Sub, where Sub extends Super. Consider two
    objects aSuper and aSub. Now if (as may be reasonable) you want it to be true
    that:

    aSuper.equals(aSub)

    then it should also be true that:

    aSub.equals(aSuper)

    In which case the 'instanceof' test in Sub.equals() must be allowing instances
    of its superclass. (This could be thought of as an application of the 'species'
    pattern I mentioned.) In such cases we are essentially saying that not only
    can Subs be substituted for Supers (in the sense of the Liskov Substitution
    Principle), but also that Supers can be substituted for Supers -- that they are
    interchangable (modulo polymorphically differing behaviour). Class hierarchies
    that have that property are certainly not ill-formed (I'd argue that they are
    exceptionally well-formed), but they are not the general rule. Normally
    substitutability only runs in one direction.

    So we see another oddness (in OO terms) about equals(). It must either (in the
    general case) fail to be symmetric (an abomination) or it must fail to be
    compatible with the LSP.

    Continuing a thought from my earlier post. Considering the shear oddness of
    equals(), and the extaordinary wide contract that it is supposed to fulfill,
    it's not surprising that it is forced to employ "unusual" techniques like
    reflection.

    -- chris
    Chris Uppal, Nov 10, 2004
    #18
  19. Chris Uppal wrote:

    > John C. Bollinger wrote:
    >
    >
    >>The one place where I find myself frequently using instanceof in Java is
    >>in equals() methods,


    > But equals() is such a very odd method. That's to say, the concept of
    > "equality" as used in programming is so very odd -- I don't think there's
    > anything specifically odd about the Java equals() method.
    >
    > It /looks/ innocous enough, but it's really very strange.


    [...]

    Agreed. Unfortunately, there is no getting around it. It is much too
    deeply ingrained in the language and class libraries.

    >>Do you have a preferred idiom to suggest?

    >
    >
    > Not really.
    >
    > Actually, I /think/[*] I prefer to express the class-test in equals() as:
    >
    > this.getClass() == anObject.getClass()
    >
    > rather than hardwiring a reference to "my" class into the code (and that also
    > avoids the potential problem, or at least ambiguity, with subclasses). But it
    > comes down to pretty-much the same thing.


    I tend to fall on the other side of the question of equality with
    instances of subclasses, so instanceof usually expresses my intent
    accurately. There is a reflective solution that would mirror instanceof
    perfectly, but I really don't see the point of doing that in such a case.

    > There's an idiom (widely used in the Smalltalk class hierarchy, for instance)
    > which is slightly more flexible than the class-test. I'm not sure I like it
    > myself -- it doesn't really cure the equals() problems, although it does help.
    > The idiom is that an object has a 'species' which is normally its own class,
    > but may be some other class (usually a superclass), and the equals() method can
    > compare species rather than classes:
    >
    > return this.getSpecies() == anObject.getSpecies()
    > && // ... rest of comparison
    >
    > The idea is that it is testing /type/ not class, and doing so idiomatically by
    > nominating (slightly arbitrarily) a specific class which is then taken to
    > exemplify the type shared by a whole category of concrete classes.


    I like that. It perfectly expresses the answer to the relevant
    question, including providing a clean solution for the subclass issue.

    > It's not something you could use directly in Java, since that would require
    > getSpecies() to be defined by java.lang.Object, though you could use instanceof
    > to emulate it.


    Which is more or less where we started, I think. At least, substituting
    an instanceof test for the equality test in your example results in
    the Java idiom that I normally use in these cases.

    > An elegant variant would be to use an interface as the
    > nominated (paradigmatic) class. Come to think of it, maybe that's how you
    > /are/ using instanceof in your applications ?


    I wish I could lay claim to such elegance, but sadly, no, my typical
    usage is more mundane.

    Thanks for the comments.

    Cheers,

    John Bollinger
    John C. Bollinger, Nov 10, 2004
    #19
  20. Stefan Schulz wrote:
    > On Wed, 10 Nov 2004 11:07:16 -0000, Chris Uppal
    > <-THIS.org> wrote:
    >
    >> John C. Bollinger wrote:
    >>
    >>> The one place where I find myself frequently using instanceof in Java is
    >>> in equals() methods,

    >>
    >> [...]
    >> Actually, I /think/[*] I prefer to express the class-test in equals() as:
    >>
    >> this.getClass() == anObject.getClass()
    >>
    >> rather than hardwiring a reference to "my" class into the code (and
    >> that also
    >> avoids the potential problem, or at least ambiguity, with
    >> subclasses). But it
    >> comes down to pretty-much the same thing.
    >>
    >> ([*] I can't remember ever implementing equals() in Java, which may be
    >> significant in itself -- or maybe I'm just in denial ;-)

    >
    >
    > This will fail if you get an Object of a subclass of your own... one
    > you could
    > compare (and which would be an instanceof your class=
    >


    I think Chris is right. The equals method has to be symmetric, according
    to the documentation. This means that superclass.equals(subclass) must
    return false
    Andrea Desole, Nov 10, 2004
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    4
    Views:
    523
  2. =?Utf-8?B?U2hhd24=?=

    Set DataGridItem dirty

    =?Utf-8?B?U2hhd24=?=, Sep 7, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    336
    =?Utf-8?B?U2hhd24=?=
    Sep 7, 2004
  3. EDom

    Page is Dirty information

    EDom, Aug 9, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    389
    =?Utf-8?B?QW5kcmVhcy5LbnVkc2VuKEFUKWJla2subm8=?=
    Aug 23, 2005
  4. Replies:
    3
    Views:
    1,636
    Bruce Barker
    Mar 20, 2006
  5. Replies:
    21
    Views:
    21,303
Loading...

Share This Page