class Shape implements Comparable <Shape>
和
class Square extends Shape
我写了一个泛型方法来查找数组中的最大元素:
public static <S extends Comparable<S>> S findMax(S[] arr) { //blablabla... return maxS; }
这两个电话给我没有错误,并做他们应该做的事情:
Shape maxShape = findMax(new Shape[]{new Shape(1), new Shape(2), new Shape(3)}); Square maxSquare = findMax(new Square[]{new Square(1), new Square(2), new Square(3)});
因此,对我来说似乎是合理的,因为Shape实现了Comparable< Shape>并且Square延伸Shape,Squares也应该是可比较的,a.k.a.Square以某种方式自动实现Comparable< Square>通过继承(特别是通过继承compareTo(Shape s)).
然而,根据我的教科书,情况并非如此:这里“我们所知道的是Square实现了Comparable< Shape> ;;因此是一个Square IS-A Comparable< Shape>,但是IS-NOT-A Comparable< Square>”,它建议一个更好的方法签名:
public static< S extends Comparable<?超级S>>.
那为什么我的公共静态< S扩展Comparable< S>>给我没问题?
—————————–更新(来源代码)—————- ————–
public class Shape implements Comparable<Shape>{ protected int area; public Shape (int i) { this.area=i; } public String toString() { return area+""; } public static void main(String[] args) { System.out.println("Bigger shape: "+findMax(new Shape[] {new Shape(2),new Shape(3)})); System.out.println("Bigger square: "+findMax(new Square[] {new Square(2),new Square(3)})); } public int getValue() { return area; } @Override public int compareTo(Shape sh) { return Integer.valueOf(area).compareTo(sh.getValue()); } public static <N extends Comparable<N>> N findMax(N[] arr) { int maxIdx=0; for (int i=1; i<arr.length; i++) if (arr[i].compareTo(arr[maxIdx])>0) maxIdx=i; return arr[maxIdx]; } } class Square extends Shape { public Square(int i) { super(i); } public int compareTo(Shape sh) { return Integer.valueOf(area%3).compareTo(sh.getValue()%3); } }
我得到的输出是
Bigger shape: 3 Bigger square: 2
获得的经验:原始问题的答案是否定的.正如Tagir Valeev指出的那样,由于Shape []的协变特性,允许在Square []上调用findMax而不进行赋值.
实际上你的代码没有编译. Javac 1.7:> "C:\Program Files\Java\jdk1.7.0_80\bin\javac.exe" GenericTest.java GenericTest.java:32: error: method findMax in class GenericTest cannot be applied to given types; Square maxSquare = findMax(new Square[]{new Square(1), new Square(2), new Square(3)}); ^ required: S[] found: Square[] reason: inferred type does not conform to declared bound(s) inferred: Square bound(s): Comparable<Square> where S is a type-variable: S extends Comparable<S> declared in method <S>findMax(S[]) 1 error
Javac 1.8:
>"C:\Program Files\Java\jdk1.8.0_40\bin\javac.exe" GenericTest.java GenericTest.java:32: error: incompatible types: inference variable S has incompatible bounds Square maxSquare = findMax(new Square[]{new Square(1), new Square(2), new Square(3)}); ^ equality constraints: Shape upper bounds: Square,Comparable<S> where S is a type-variable: S extends Comparable<S> declared in method <S>findMax(S[]) 1 error
ECJ 3.10.2:
>java -jar org.eclipse.jdt.core_3.10.2.v20150120-1634.jar -source 1.7 GenericTest.java ---------- 1. ERROR in C:\projects\Test\src\GenericTest.java (at line 32) Square maxSquare = findMax(new Square[]{new Square(1), new Square(2), new Square(3)}); ^^^^^^^ Bound mismatch: The generic method findMax(S[]) of type GenericTest is not applicable for the arguments (GenericTest.Square[]). The inferred type GenericTest.Square is not a valid substitute for the bounded parameter <S extends Comparable<S>> ---------- 1 problem (1 error)
所有编译器都会按预期生成正确的错误消息.如果将findMax方法声明为public static< S extends Comparable<?超级S>> S findMax(S [] arr),然后错误消息正确消失.
发布完整代码后更新问题变得清晰.不同之处在于您没有将findMax的结果赋给变量:
System.out.println("Bigger shape: "+findMax(new Shape[] {new Shape(1),new Shape(3)})); System.out.println("Bigger square: "+findMax(new Square[] {new Square(3),new Square(2)}));
因此在两种情况下< S>被推断为Shape为Square []类型IS-A Shape []类型.