【问题标题】:Java GenericClass< ? extends Interface> as a ParameterJava 通用类< ?扩展接口>作为参数
【发布时间】:2020-01-15 05:32:18
【问题描述】:
public interface A {}
public interface B {}
public class Test implements A{}
public class Test2 {}

我创建了一个方法来检查一个类是否实现了一个接口。我希望我的方法只接受通用接口而不是所有类对象。

方法

    public static boolean containsInterface(Class clazz, Class intf)
    {
    try
    {
        Validate.isTrue(intf.isInterface());
        if(clazz.isInterface())
            return JavaUtil.isClassExtending(intf, clazz);
        for(Class c : ClassUtils.getAllInterfaces(clazz))
        {
            if(JavaUtil.isClassExtending(intf, c))
                return true;
        }
    }
    catch(Throwable t)
    {
        t.printStackTrace();
    }
    return false;
}

由于 Test.class 和 Test2.class 不是 2d 参数上的接口,我希望它出现编译错误,因为 2d 参数必须是接口类

containsInterface(Test.class, Test.class);
containsInterface(Test.class, Test2.class);

我的方法可接受的使用

containsInterface(Test2.class, A.class);
containsInterface(Test.class, B.class);

我尝试过的

public static boolean containsInterface(Class clazz, Class<? extends Interface> intf)

我目前检查参数中的类是否是接口然后抛出异常。如果它不是接口,我宁愿强迫人们不能调用该方法开始

我知道 Annotations 和 Enum 对象可用作类签名,以确保人们正确使用参数,但我似乎找不到接口本身的参数。

有人告诉我泛型不支持接口或抽象类类型即使在 jre 9-13+ 中也是如此

【问题讨论】:

  • 你能解释一下containsInterface()应该做什么吗?
  • 它判断一个类是否有一个指定的接口。您输入接口类。我已经让它工作了我只想将 2d 接口参数强制为接口
  • 重新打开该问题需要进行几次重新投票。给点时间吧。
  • 作为对您的快速回答,没有用于强制静态type作为接口的构造。 Class 对象将包括接口(以及枚举和注释以及具体或抽象类等)
  • 另一个快速的答案是使用intf.isAssignableFrom(clazz))(甚至instanceof),但这些检查几乎总是代码异味;这就是我们想知道用例的原因,因为可能有更好的方法。还要记住泛型(如&lt;? extends Something&gt;)在运行时不可用。

标签: java class parameters interface reflect


【解决方案1】:

您不能使用类型控制系统将参数强制为任何接口实现。如果您想仅使用abstract 修饰符强制Class&lt;?&gt;,则同样适用。我不确定这是否真的需要做简单类型isInterface assert 是

  1. 直截了当
  2. 干净
  3. 稳健
  4. 简单易懂
  5. 容易出错
  6. 可测试

JDK 工程师也不关心这一点。将使用(但没有)这种机制的一个完美示例是 JDK 动态代理创建。您只能创建一个接口(或一组)但不能创建类的代理。

我认为编写自己的前处理器并不值得。此外,它不是通用的-因为您假设必须在编译时知道运行时类型-动态加载的类等呢?

【讨论】:

    【解决方案2】:

    java 中的接口没有可以在泛型模式下使用的超类。

    如果你尝试使用反射获取接口的超类,则返回 null。

    public static void main (String [] args) {
            System.out.println(A.class.getSuperclass());
    }
    
    interface A {}
    

    输出:

    null
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 2021-12-07
      • 1970-01-01
      • 2012-11-06
      相关资源
      最近更新 更多