java声明泛型
我在静态方法和字段中定义泛型时遇到问题
假设我有一个简单的接口,所有类都使用它,它包含一个名为value
的T
类型的字段:
public interface HasValue<T> {
// Getter:
public T value();
// Setter:
public void setValue(T value);
}
如果我有一个类型为N
的对象数组,它实现了HasValue<T>
,我可能需要对这个数组进行排序。一种经典的方法是使用value
字段比较那些N
对象:如果T
实现了Comparable<T>
接口,并且arg0
和arg1
都是N类型,那么arg0.compareTo(arg1)
将等于arg0.value().compareTo(arg1.value())
我们的目标是创建一个可用的、不耗时的、可能的简单方法来获得上述情况
每次我需要类似的东西时,都可以创建一个自定义Comparator<N>
。这将迫使我每次都要写代码:肯定很耗时
我可以直接在接口中创建Comparator<N>
。第一次尝试是创建一个方法:
- 它需要是一个默认方法。部分代码将测试类
T
是否实现了Comparable
接口,为此,我需要一个T
类的示例:使用this.value().getClass()
是最快的方法。对于静态方法,我不能使用this
李> 我需要说明
N
类实现了接口HasValue<T>
,否则计算机不会知道public default <N extends HasValue<T>> Comparator<N> COMPARE_BY_VALUE() throws Exception{ if(Comparable.class.isAssignableFrom(this.value().getClass())) return new Comparator<N>() { public int compare(N arg0, N arg1) { Comparable value0 = (Comparable) arg0.value(), value1 = (Comparable) arg1.value(); return value0.compareTo(value1); } }; else throw new Exception("The class of the value does not implement the interface Comparable.\n"); }
- 这个策略有效。。。仅仅它很笨拙,涉及到rawtypes,每次都创建
Comparator<N>
李>
- 这个策略有效。。。仅仅它很笨拙,涉及到rawtypes,每次都创建
第二次尝试:创建静态字段
策略是将测试问题与其他问题分开。默认方法将执行测试:如果成功,该方法将返回静态
Comparator
,否则返回异常public default <N extends HasValue<T>> Comparator<?> COMPARE_BY_VALUE() throws Exception{ if(Comparable.class.isAssignableFrom(this.value().getClass())) return COMPARE_BY_VALUE; else throw new Exception("The class of the value does not implement the interface Comparable.\n"); } public static Comparator<HasValue> COMPARE_BY_VALUE = new Comparator() { public int compare(Object arg0, Object arg1) { Comparable value0 = (Comparable) ((HasValue)arg0).value(), value1 = (Comparable) ((HasValue)arg1).value(); return value0.compareTo(value1); } };
在声明静态字段时,我(不幸地)不能声明类似
public static <T, N extends HasValue<T>> Comparator<N> COMPARE_BY_VALUE
的内容。这迫使我返回一个Comparator<HasValue>
:不是我想要的使用通配符,我可以获得关闭的内容:
public default <N extends HasValue<T>> Comparator<?> COMPARE_BY_VALUE() throws Exception{ if(Confrontable.class.isAssignableFrom(this.value().getClass())) return COMPARE_BY_VALUE; else throw new Exception("The class of the value does not implement the interface Comparable.\n"); } public static Comparator<? extends HasValue<? extends Comparable<?>>> COMPARE_BY_VALUE = new Comparator() { public int compare(Object arg0, Object arg1) { Comparable value0 = (Confrontable) ((HasValue<?>)arg0).value(), value1 = (Confrontable) ((HasValue<?>)arg1).value(); return value0.compareTo(value1); } };
这种修改(理论上)将返回一个
Comparator<N>
,其中N
扩展HasValue<T>
,T
扩展Comparable<U>
,而U
实际上是T
- 因为JVM将{
}中的每一个{ }解释为一个潜在的新类:三个{ }意味着三个新类({ }、{ }和{ }),而{ }恰好实现了{ },因此{ }和{ }是一个相同的类李>
- 因为JVM将{
- 我仍然有大量的原始类型李>
- 。。。但至少我每个
N
和T
只有一个{}李>
现在,虽然最后一个策略似乎有效,但我想知道是否有更好的方法来实现我的目标
我最初的想法是说
public static <T extends Comparable<T>, N extends HasValue<T>> Comparator<N> COMPARE_BY_VALUE = new Comparator() {
public int compare(N arg0, N arg1) {
return arg0.value().compareTo(arg1.value());
}
};
并获得一个不带通配符的Comparator<N>
。但是,这会发送所有类型的错误。有人有主意吗
# 1 楼答案
只要做:
这意味着:对于实现
Comparable
的每个类型T
,此方法返回可以比较HasValue<T>
的comparatorJava可能无法正确推断这种复杂结构中的类型。您可能必须显式添加类型:
或:
请记住,许多程序员过度使用泛型。通常有一种更简单的方法来实现相同的功能,同时仍然保持类型安全性