Java中泛型方法的键入行为

问题描述 投票:-1回答:2

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

java generics runtime type-erasure generic-method
2个回答
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
投票

在实例方法中,将这个类型为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);

© www.soinside.com 2019 - 2024. All rights reserved.