Search code examples
javainheritancerttityping

Java isInstance vs instanceOf operator


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?


Solution

  • 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