Java中泛型方法的键入行为

时间:2017-12-20 21:01:58

标签: java generics runtime type-erasure generic-method

我试图理解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"]

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

在实例方法中,您比较对象,其类型为K,V  与另一个类型为X,Y的Pair对象。

所以,没关系:你有Pair<Integer, String> p1(K =整数,V =字符串),你调用与Pair<Integer, Integer> e1比较(X =整数,Y =整数)

但对于静态方法,没有K和V类型。您只定义了N和M.  并明确定义两个参数必须是N,M类型。你没有它,因为对于p1 N =整数和M = String,而对于e1 N =整数和M =整数。

要使通用静态方法比较任何类的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);吗?