Java isInstance против оператора instanceOf

Вся эта штука с дженериками сбивает меня с толку, и тем более RTT.

Специфика? Ну вот суть:

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? Должен ли я использовать последний?


person rybit    schedule 10.11.2010    source источник


Ответы (3)


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

В возвращаемом типе этого метода нет ничего гибкого.

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 является экземпляром ожидаемого типа, но ожидаемый тип может быть другим типом каждый раз, когда вызывается метод

person Dónal    schedule 10.11.2010
comment
Ваш пример использования isInstance является обратным. Ожидается Type.isInstance(myVar); - person Affe; 10.11.2010
comment
Спасибо за разъяснение - мне определенно нужно было замедлиться и подумать, когда я писал этот код. С тех пор он изменил форму, чтобы быть действительно полезным. Спасибо еще раз! - person rybit; 16.11.2010

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

expectedReturn.isInstance(SomeRelatedClass.class)

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

Class.class.isInstance(SomeRelatedClass.class);

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

Object.class.isAssignableFrom(Class.class);

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

Class klass = ...;
Object o = klass;
person vanza    schedule 10.11.2010

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

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

Class.class.isInstance(SomeRelatedClass.class);

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

expectedReturn.isInstance(new SomeRelatedClass());
person Affe    schedule 10.11.2010