声明泛型

时间:2015-08-06 11:35:22

标签: java generics

我在静态方法和字段中定义泛型时遇到问题。

假设我有一个简单的接口,包含名为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>。第一个尝试是创建一个方法:

  1. 它必须是默认方法。部分代码将测试类Comparator<N>是否实现T接口,为此我需要Comparable类的示例:使用T是最快的办法。使用静态方法我无法使用this.value().getClass()
  2. 我需要明确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"); }
  3. 第二次尝试:创建静态字段

    • 策略是将测试问题与其他问题分开。默认方法将执行测试:如果成功,该方法将返回静态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>扩展NHasValue<T>扩展TComparable<U>实际上是U

      • 这是因为T中的每个?都被JVM解释为潜在的新类:三个Comparator<? extends HasValue<? extends Comparable<?>>>表示三个新类(?NT),而U实现了T - 因此Comparable<T>U是同一个。
    • 我还有很多原型......
    • ...但至少我对TComparator只有一个 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()); } }; 。然而,这会发送所有类型的错误。有人有想法吗?

1 个答案:

答案 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());

请记住,很多程序员都过度使用泛型。通常有一种更简单的方法来实现同样的目标 - 同时仍然保持类型安全。