Java isInstance vs instanceOf运算符

时间:2010-11-10 00:15:06

标签: java inheritance rtti typing

整个泛型的东西有点像扔我一个循环,更多的是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运算符之间的区别?我应该使用后者吗?

3 个答案:

答案 0 :(得分:29)

  

这样我就可以在实际的帮助器中灵活地分配查询返回类型。

此方法的返回类型没有任何灵活性

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的实例,但是每次调用方法时expectedType都可以是不同的类型

答案 1 :(得分:3)

Class.isInstance()不像您的代码所期望的那样工作。它会测试传递给它的对象是否是该类的实例。在你的代码中:

expectedReturn.isInstance(SomeRelatedClass.class)

您传递的对象是Class对象。试试这个,返回true:

Class.class.isInstance(SomeRelatedClass.class);

您可能正在寻找的是Class.isAssignableFrom(),例如:

Object.class.isAssignableFrom(Class.class);

意味着你可以这样做:

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

答案 2 :(得分:1)

isInstance的预期参数是一个对象,它可以是类对象所代表的类的实例。你要比较它的是一个类的实例...... java.lang.Class!所以它不会匹配。

例如,确实如此:

Class.class.isInstance(SomeRelatedClass.class);

也是如此(没有关于以这种方式实际构建查询助手的完整性的架构评论)

expectedReturn.isInstance(new SomeRelatedClass());