如何检查一个泛型类是否实现了某个接口

4

我有这个类:

public class Bird extends AbstractEntity<Long> implements IHasWings {
}

还有一些继承了AbstractEntity类但没有实现IHasWings接口的其他类,例如:

public class Cat extends AbstractEntity<Long>{
}

我将这些类作为类型参数传递给它们的DAO类,像这样:

public class BirdDAO extends AbstractDAO<Bird, Long> { ... }

并且。
public class CatDAO extends AbstractDAO<Cat, Long> { ... }

所有DAO类都继承自AbstractDAO类。

AbstractDAO类中,我有以下代码:

public abstract class AbstractDAO<T extends AbstractEntity<ID>, ID extends Serializable> { 
    public List<T> findAll(){ 
        AbstractEntity entity = ...
        if (entity instanceof IHasWings) {
            IHasWings entityWithWings = (IHasWings) entity;
            //Do something with entityWithWings.getWingSize();
        }else{
            //Do something else
        }
    }
}

我希望测试传递的类型参数是否实现了 IHasWings,如上所示,但我找不到方法来实现它。
我尝试了以下方法:
Class<T> entity = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
    .getActualTypeArguments()[0];
if (entity instanceof IHasWings) {...}

出现这个错误: Class<T> 和 IHasWings 的条件操作数类型不兼容

我该如何解决?


https://dev59.com/pWEh5IYBdhLWcg3wYSrt - PeterMmm
1
你在底部的 if (entity instanceof IHasWings) 等同于 class instanceof class。按照定义,类不是任何实例。 - Michael
1个回答

4
你的检查有误,因为它正在验证 Class<?> 的实例是否是 IHasWings 的实例。编译器会阻止使用没有关系的对象和类型进行 instanceof 检查(java.lang.Class 对象永远不能是你的 IHasWings 接口的实例)。
你需要找到一种方法来确定 IHasWings 是否与 entity 中的类对象兼容。为此,你需要使用以下代码:
IHasWings.class.isAssignableFrom(entity)

根据Java文档java.lang.Class.isAssignableFrom(Class<?> cls)):

确定由该Class对象表示的类或接口是否与指定的Class参数表示的类或接口相同,或者是其超类或超接口。


谢谢您的帮助,但我该如何转换“entity”,以便我可以执行“entity.getWingSize()”? - Renaud is Not Bill Gates
@IchigoKurosaki 你的意思是在findAll里面吗?你的问题中有两个名为entity的变量,一个是Class,另一个是AbstractEntity。 我认为在AbstractDAO中的方式将会起作用,假设实际创建AbstractEntity entity实例时使用了正确的类来创建对象。 [但是为什么要使用原始类型AbstractEntity呢?这是问题的标志吗?还是因为您正在使用反射实例化对象?] - ernest_k
我写了 AbstractEntity entity = ... 是因为我不知道如何实例化 entity,那不是最终代码。 - Renaud is Not Bill Gates
@IchigoKurosaki 对的。那么,如果在运行时使用了正确的AbstractEntity子类,则if (entity instanceof IHasWings)将起作用。 - ernest_k
嗯,实际上当我这样做时,我会得到这个编译错误:不兼容的条件操作数类型Class<T>和IHasWin - Renaud is Not Bill Gates
@IchigoKurosaki,这就是我在问题中说你有两个名为entity的变量的原因。第二个会导致编译器错误(这也是我的答案所涉及的),但第一个(在你的AbstractDAO.findAll方法中)不会。 - ernest_k

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