【问题标题】:Is it possible to evaluate whether a class interface extends a certain base class?是否可以评估类接口是否扩展了某个基类?
【发布时间】:2023-03-20 02:29:01
【问题描述】:

我有一个将泛型类接口作为参数的方法,我想检查提供的接口是否扩展了某个基类,如果没有,我将抛出异常。是否可以做类似的事情:

public void genericMethod(Class<T> c) {
    if (!(c instanceof baseClass)) {
        throw new Exception("Must be instance of base class");
    }
}

即使有可能,这是否被认为是好的做法?还是java泛型应该遵循ducktyping的相同原则?

【问题讨论】:

    标签: java generics


    【解决方案1】:

    您可以使用Class.isAssignableFrom:

    if (baseClass.isAssignableFrom(c)) {
      ...
    }
    

    此代码假定baseClass 是Class 类型的变量(字段、局部变量等)。如果baseClass 是类的名称(这将违反Java 约定),那么请改用baseClass.class,正如Pshemo 在cmets 中所建议的那样。

    来自文档:

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

    【讨论】:

    • 更准确地说是baseClass.class.isAssignableFrom(c)。无论如何+1
    • 哦,我明白你的意思了。但是,没有唯一的通用解决方案:如果baseClass 是Class(正如我最初假设的那样,基于Java 约定),则不能使用.class。如果是类的name,则必须使用.class。更准确地说,如果baseClass 是一个类的名称,那么我最初编写的代码甚至无法编译;但是,如果它是 Class 类型的变量,那么您的代码甚至无法编译。
    • 由于 OP 使用了instanceof baseClass,我认为baseClass 是接口的名称而不是类引用,但是在 SO questins 上一切皆有可能:)
    【解决方案2】:

    解决您问题的核心部分;当你走泛型的道路时,如果你有它会更好看:

           public void genericMethod(Class<? extends BaseClass> c) {
              // do what you want
            }
    

    ? 通配符告诉编译器只有BaseClass 的子类是可接受的参数,本质上是为您执行instanceOf 检查。

    这几乎消除了在编译期间滥用您的方法的可能性

    另见

    【讨论】:

      猜你喜欢
      • 2014-01-19
      • 2019-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      • 2015-01-18
      • 1970-01-01
      相关资源
      最近更新 更多