如何验证泛型类型扩展了Java中的另一个类/接口?

时间:2014-03-14 08:05:32

标签: java generics interface

我有一个泛型K,我想验证K是否实现了Comparable接口。 这是我的代码:

public class HashMapVectorSimilarity<K> {
    static public <K> double calculateSimilarity(HashMap<K, Double> hashMap1, HashMap<K, Double> hashMap2) {
        if (Comparable.class.isAssignableFrom(K)) {//
                  }
       }

但代码不起作用。 我不想将所有K限制为实施Comparable。我已经有了另一个TreeMapVectorSimilarity类。如果K实现了接口Comparable,我将使用TreeMapVectorSimilarity类返回结果。

您认为我怎么能解决这个问题? 感谢。

3 个答案:

答案 0 :(得分:4)

如果要强制执行只能使用实现K的{​​{1}}类型,可以在编译时检查它:

Comparable

这是最简单的,可能是最好的。

如果您想要运行时检查,则不能按照您编写的方式执行此操作,因为类型擦除。泛型在Java中的工作方式是编译器会检查所有类型,但会删除它们,因此它们在运行时不可用。

因此,如果您希望运行时类型可用,则需要明确传入public class HashMapVectorSimilarity<K extends Comparable<K>> { ... } 对象:

Class

或者您可以将 static public <K> double calculateSimilarity( HashMap<K, Double> hashMap1, HashMap<K, Double> hashMap2, Class<K> clazz) { if (Comparable.class.isAssignableFrom(clazz)) { ... } } 传递给构造函数并将其存储在对象中。

答案 1 :(得分:0)

正如Leri所述,将您的代码更改为:

public class HashMapVectorSimilarity<K extends Comparable<K>> {
}

答案 2 :(得分:0)

如果没有在某个时刻专门存储Class<K>,你就无法真正做到这一点(例如,将其作为参数传递给方法,或者将其传递给构造函数并将其保存在字段中);请参阅Get generic type of class at runtime了解其中的一些选项。

如果哈希映射不是空的,你可以通过获取其中一个键并抓住它的类来破解它,但我强烈建议不要这样做。

最好的解决方案是确保类型实现您感兴趣的界面,如果可能,例如:

public class HashMapVectorSimilarity<K extends Comparable<K>> {
    ...
}

如果您不愿意将所有K限制为实施Comparable<K>,那么您的下一个最佳选择是将该类本身作为参数传递给某个地方 - 尽管在这种情况下,您应该真的问自己,HashMapVectorSimilarity是否真的让感觉Comparable类型。