Java isInstance vs instanceOf operator

rybit picture rybit · Nov 10, 2010 · Viewed 48.4k times · Source

The whole generics thing is kinda throwing me for a loop, and more so the RTT.

Specificis? Ah well here's the gist:

enum QueryHelper {
  query1,
  query2;
  static <T> QueryHelper getQueryHelper (Class<T> expectedReturn) {
    if (expectedReturn.isInstance (SomeRelatedClass.class))
      return query1;
    else
      return query2;
  }
}

and then I would call it like so:

...
QueryHelper helper = QueryHelper.getQueryHelper(SomeRelatedClass.class);
...

This is so that I can really flexibly assign the query return type in the actual helper. It does some casting and object creation. What I am seeing is that there is no match, should I be doing this some other way? Or is the whole idea just bad?

And the real heart of this is that I don't understand the difference between class.isInstance and the instanceOf operator? Should I be using the latter?

Answer

D&#243;nal picture Dónal · Nov 10, 2010

This is so that I can really flexibly assign the query return type in the actual helper.

There is nothing flexible about the return type of this method

static <T> QueryHelper getQueryHelper (Class<T> expectedReturn) {
    if (expectedReturn.isInstance (SomeRelatedClass.class))
      return query1;
    else
      return query2;
}

It will always return an instance of QueryHelper. If you want the return type to be flexible you would need to define it as something like:

static <T> T getQueryHelper (Class<T> expectedReturn) {
}

Now the return type is flexible, because it will depend on the type of the argument

And the real heart of this is that I don't understand the difference between class.isInstance and the instanceOf operator?

The difference is that instanceof does a type-check that is fixed at compile-time, for example:

static boolean isInstance(Object myVar) {
    return (myVar instanceof Foo);
}

will always check that myVar is an instance of Foo, whereas

static <T> boolean isInstance(Object myVar, Class<T> expectedType) {
    return expectedType.isInstance(myVar);
}

will check that myVar is an instance of expectedType, but expectedType can be a different type each time the method is called