Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

isInstance & instanceof - Why there's no generic way? [duplicate]

I understand the usage & motive of both of these - isInstance is Runtime Equivalent of instanceOf.But , why do we have two ways? Why could not we have a generic implementation of instanceof keyword which caters to both the cases?

For Example , this is the way these are used currently:

1)instanceof

public Collection<String> extract(Collection<?> coll) {
    Collection<String> result = new ArrayList<String>();
    for (Object obj : coll) {
      if (obj instanceof String) {
        result.add((String) obj);
      }
    }
    return result;
}

2)isInstance

public <T> Collection<T> extract(Collection<?> coll, Class<T> type) {
    Collection<T> result = new ArrayList<T>();
    for (Object obj : coll) {
      if (type.isInstance(obj)) {
        result.add((T) obj);
      }
    }
    return result;
}

So , my Question is why can't we have a generic implementation of instanceof operator that caters to the 2nd exmaple above as below? (i.e. Why can't it resolve the type at runtime?)

public <T> Collection<T> extract(Collection<?> coll, Class<T> type) {
    Collection<T> result = new ArrayList<T>();
    for (Object obj : coll) {
      if (obj instanceof type) {
        result.add((T) obj);
      }
    }
    return result;
}
like image 575
nikel Avatar asked Oct 05 '22 13:10

nikel


1 Answers

Some background:

  • The instanceof keyword / syntax was in Java from Java 1.0 (IIRC).

  • The Class.isInstance method was introduced in Java 1.1 (per the javadoc).

  • Generics were introduced in Java 1.5 (aka 5.0), though you don't need generics to make your example work.


The syntax for instanceof is <expr> 'instanceof' <type>. To support your suggestion they would have had to change that to <expr> 'instanceof' <type> | <expr>. That has a couple of problems:

  • It potentially introduces grammatical ambiguity. (One would have to do a full analysis to determine if that was the case.)

  • It potentially introduces semantic ambiguity. The problem is a bit obscure, but type names and variable names are in different namespaces, so it is possible to have both a variable and a class called Something. If you do, does obj instanceof Something refer to the variable or the class? And what about obj instanceof Something.class?

The other issue is that this "enhancement" would have little impact on the typical programmer's ability to write correct code. Basically, it is a cosmetic change. As such, there is no real justification for making the change.


Now I have no idea if the Java team even considered this option. (You would have to ask them!). And if they did, I've no idea why they rejected it. But whatever the answer to those questions are, Java doesn't work this way ... and you will just have to live with it.

(If there is another "Project Coin" for Java 9, you could maybe propose this idea, but frankly I don't imagine it would get much support. Many ideas that were more worthy have failed to make the cut.)


1) By grammatical ambiguity do you mean the grammar would become complicated?as you have shown , it should be possible to write the parsing grammar that way..

No. I mean that the grammar could be ambiguous; i.e. a given utterance could be parsed in two different ways, meaning two different things. You then need some additional rule(s) (in addition to the grammar) to sort out which parse is the correct one.

2) If the name resolution in second comment introduces semantic ambiguity , why shouldn't it be possible to qualify the name with the appropriate namespace(variables or types)

The problem is that this is all extra linguistic complexity for specification writer to specify, the compiler writer to implement, and the programmer to understand.

And what is the real benefit? Just a bit of syntactic "elegance" ... which actually is not as elegant as it seems when you consider the special rules that come into play at various levels to make it "work".

like image 143
Stephen C Avatar answered Oct 12 '22 15:10

Stephen C