Java isInstance与instanceOf运算符的差异

25

整个通用类型的概念让我有些困惑,特别是运行时类型信息。

具体来说?好吧,这是要点:

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个回答

30

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

该方法的返回类型并不灵活。

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可能是不同的类型


isInstance 的使用示例是错误的。应该是 expectedType.isInstance(myVar); - Affe
谢谢你澄清这个问题 - 当我编写这段代码时,我确实需要放慢速度并思考。现在它已经变得更加有用了。再次感谢! - rybit

4

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

expectedReturn.isInstance(SomeRelatedClass.class)

您传递的对象是一个类对象。请尝试使用以下代码,它会返回true:
Class.class.isInstance(SomeRelatedClass.class);

你可能正在寻找的是Class.isAssignableFrom(),例如:
Object.class.isAssignableFrom(Class.class);

这意味着你可以这样做:

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

1
isInstance 的预期参数是一个对象,该对象可能是您的类对象所表示的类的实例。您正在将其与类的实例进行比较...java.lang.Class!因此它不会匹配。
例如,将是真的:
Class.class.isInstance(SomeRelatedClass.class);

同时也是正确的(不考虑实际构建查询助手的架构评论)

expectedReturn.isInstance(new SomeRelatedClass());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接