我在静态方法和字段中定义泛型时遇到问题。
假设我有一个简单的接口,包含名为T
的{{1}}字段的所有类使用:
value
如果我有一个public interface HasValue<T> {
// Getter:
public T value();
// Setter:
public void setValue(T value);
}
类型的对象数组来实现N
,我可能需要订购这个数组。一种经典的方法是使用HasValue<T>
字段比较这些N
对象:如果value
实现T
接口,Comparable<T>
和arg0
都是类型为N,则arg1
将等于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");
}
。第二次尝试:创建静态字段。
策略是将测试问题与其他问题分开。默认方法将执行测试:如果成功,该方法将返回静态Comparator<N>
,否则为异常。
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解释为潜在的新类:三个Comparator<? extends HasValue<? extends Comparable<?>>>
表示三个新类(?
,N
和T
),而U
实现了T
- 因此Comparable<T>
和U
是同一个。T
和Comparator
只有一个 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());
}
};
。然而,这会发送所有类型的错误。有人有想法吗?
答案 0 :(得分:0)
只是做:
<div ng-controller="MyCtrl">
<button ng-click="storeTime()">Button A</button>
Time A: {{timeA}}
</div>
这样做:对于实现static <T extends Comparable<T>> Comparator<HasValue<T>> createValueComparator() {
return new Comparator<HasValue<T>>() {
@Override
public int compare(HasValue<T> o1, HasValue<T> o2) {
return o1.value().compareTo(o2.value());
}
};
}
的每个类型T
,此方法返回可以比较Comparable
的比较器。
Java可能无法在这种复杂的结构中正确推断类型。您可能必须明确添加类型:
HasValue<T>
或:
Collections.sort(list, Main.<Integer> createValueComparator());
请记住,很多程序员都过度使用泛型。通常有一种更简单的方法来实现同样的目标 - 同时仍然保持类型安全。