Оператор Java isInstance vs instanceOf

Вся древовидная вещь бросает меня на цикл, а тем более RTT.

Specificis? Ах, вот суть:

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

а затем я бы назвал его так:

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

Это так, что я могу действительно гибко назначить тип возвращаемого запроса в фактическом помощнике. Он выполняет некоторые кастинга и создания объектов. Я вижу, что нет совпадения, должен ли я делать это по-другому? Или вся идея просто плохая?

И в самом деле, я не понимаю разницы между class.isInstance и оператором instanceOf? Должен ли я использовать последний?

Ответ 1

Это так, что я могу действительно гибко назначить тип возвращаемого запроса в фактическом помощнике.

Нет ничего гибкого в отношении типа возврата этого метода

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

Он всегда будет возвращать экземпляр QueryHelper. Если вы хотите, чтобы тип возвращаемого значения был гибким, вам необходимо определить его как нечто вроде:

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

Теперь тип возврата является гибким, поскольку он будет зависеть от типа аргумента

И в самом деле, я не понимаю разницы между class.isInstance и оператором instanceOf?

Разница в том, что instanceof проверяет тип, который фиксируется во время компиляции, например:

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

всегда будет проверять, что myVar является экземпляром Foo, тогда как

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

будет проверять, что myVar является экземпляром ожидаемого типа, но expectedType может быть другим типом каждый раз, когда метод вызывается

Ответ 2

Class.isInstance() не работает, как ожидает ваш код. Он проверяет, является ли объект, который вы передаете ему, экземпляром класса. В вашем коде:

expectedReturn.isInstance(SomeRelatedClass.class)

Объект, который вы передаете, является объектом класса. Попробуйте это вместо этого, которое возвращает true:

Class.class.isInstance(SomeRelatedClass.class);

Что вы, вероятно, ищете, это Class.isAssignableFrom(), например:

Object.class.isAssignableFrom(Class.class);

Значит, вы можете это сделать:

Class klass = ...;
Object o = klass;

Ответ 3

Ожидаемый аргумент isInstance - это объект, который может быть экземпляром класса, который представляет ваш объект класса. То, к чему вы сравниваете это, является экземпляром класса... java.lang.Class! Так что это не будет соответствовать.

например, было бы верно:

Class.class.isInstance(SomeRelatedClass.class);

Также было бы правдой (без архитектурного комментария к здравомыслию о том, что вы действительно создаете своего помощника запроса)

expectedReturn.isInstance(new SomeRelatedClass());