我试图理解Java中静态和非静态泛型方法之间的区别:
public class Pair<K, V> {
private K key;
private V value;
//the type of the _this_ object and the argument should be the same (just like in scompare)?
public <X, Y> boolean compare(Pair<X, Y> p2) {
return key.equals(key) && value.equals(value);
}
public static <N, M> boolean scompare(Pair<N, M> v1, Pair<N, M> v2) {
return v1.key.equals(v2.key) && v1.value.equals(v2.value);
}
}
除了scompare是静态的事实之外,行为不应该是不同的。我觉得奇怪的是以下内容:
Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, Integer> e1 = new Pair<>(4, 3);
//causes compile-time error (as it should)
System.out.println("e1 scompare p1: " + Pair.scompare(e1, p1));
//no compile-time error --- why?
System.out.println("e1 compare p1: " + e1.compare(p1));
编译时错误是一个参数的类型为Pair<Integer,Integer>
,另一个参数的类型为Pair<Integer,String>
。
所以我的问题是:为什么e1.compare(p1)
不会导致编译时错误?
这个MWE的文件:
Pair.java:https://pastebin.com/rmY9M0gk
D1.java:https://pastebin.com/1MpvPXBC
[平台:javac 1.8.0_151
openjdk version "1.8.0_151"
]
public <X, Y> boolean compare(Pair<X, Y> p2) {
return key.equals(key) && value.equals(value);
}
应该
public boolean compare(Pair<K, V> p2) {
return key.equals(key) && value.equals(value);
}
...如果你想让它无法编译。按照目前的情况,你的compare
方法被编写为接受任何Pair
。
在实例方法中,将这个类型为K,V的Pair对象与另一个类型为X,Y的Pair对象进行比较。
所以,没关系:你有Pair<Integer, String> p1
(K =整数,V =字符串),你打电话与Pair<Integer, Integer> e1
比较(X =整数,Y =整数)
但对于静态方法,没有K和V类型。您只定义了N和M并明确定义了两个参数必须是N,M类型。并且你没有它,因为对于p1 N = Integer和M = String,而对于e1 N = Integer和M = Integer。
要使通用静态方法比较任何类的Pair对象,您必须为两个参数定义所有类型:as
public static <N, M,P,T> boolean scompare(Pair<N, M> v1, Pair<P, T> v2)
顺便说一句:key.equals(key) && value.equals(value);
- 这没有任何意义。你的意思是key.equals(p2.key) && value.equals(p2.value);
?