我有一个配对接口(interface),例如
public interface CompositeKeyType<K1, K2> {
public K1 getKey1();
public K2 getKey2();
}
以及实现:
package com.bcsg.creditcardrecords;
public class CompositeKeyImplementer<K1, K2> implements
CompositeKeyType<K1, K2> {
private K1 key1;
private K2 key2;
public CompositeKeyImplementer() {
this.key1 = null;
this.key2 = null;
}
public CompositeKeyImplementer(K1 key1, K2 key2) throws IllegalArgumentException {
if (key1.equals(key2)){
throw new IllegalArgumentException("both keys cannot be equal");
}
this.key1 = key1;
this.key2 = key2;
}
@Override
public K1 getKey1() {
return this.key1;
}
@Override
public K2 getKey2() {
return this.key2;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof CompositeKeyImplementer<?, ?>)) {
return false;
}
if (!(((CompositeKeyImplementer<?, ?>) obj).getKey1().equals(this.key1))
|| !(((CompositeKeyImplementer<?, ?>) obj).getKey2()
.equals(this.key2))) {
return false;
}
return true;
}
}
现在......我还有一个抽象类:
public abstract class AbstractBankCardDetailsHolder<K, V> {
private NavigableMap<K, V> cardData;
public AbstractBankCardDetailsHolder() {
cardData = new TreeMap<K, V>();
}
public AbstractBankCardDetailsHolder(K key, V value){
cardData.put(key, value);
}
public NavigableMap<K, V> getCardData(){
return this.cardData;
}
public void setCardData(NavigableMap<K,V> cadData){
this.cardData.clear();
this.cardData.putAll(cardData);
}
}
我在这里概括一下(它会出现错误):
public class CompositeKeyBasedCreditCardDetailsHolder<? extends K, ? extends V> extends
AbstractBankCardDetailsHolder<? extends K, ? extends V> {
private CompositeKeyImplementer<? extends K, ? extends K> numberProviderPair;
// ....... TBC
}
我的印象是?通配符意味着?TypeUnknown?它将解析类型@Runtime。然而,我注意到在写这个问题时,我的 CompositeKeyImplementer.java 类的 equals 方法中也有通配符。这是我无法实现的事情吗,因为 JVM 无法在运行时解析不同的通配符排列(例如这个)?
最佳答案
根据我可以从您的示例代码中得出的结果:
1) 您的CompositeKeyImplementer
需要通用。它实现了一个通用接口(interface),稍后您将其称为通用类型。
public class CompositeKeyImplementer<K1, K2> implements CompositeKeyType<K, V> {
...
2) 您想要 CompositeKeyImplementor<K1, K2>
具有 K
子类型的任何类型参数作为 CompositeKeyBasedCreditCardDetailsHolder
中的一个字段类(class)。
因此,您在调用 CompositeKeyImplementor
时使用通配符作为类型参数。您不要在 CompositeKeyBasedCreditCardDetailsHolder
的泛型类型声明中将它们用作类型参数
public class CompositeKeyBasedCreditCardDetailsHolder<K, V> extends
AbstractBankCardDetailsHolder<K, V> {
private CompositeKeyImplementer<? extends K, ? extends K> numberProviderPair;
// ....... TBC
}
你的意思是:
- 我正在声明一个通用
CompositeKeyBasedCreditCardDetailsHolder
带类型参数K, V
. - 该类型有一个名为
numberProviderPair
的字段 - 它本身就是一个泛型类型
CompositeKeyImplementer<K1, K2>
- 事实上它本身可以是任何
CompositeKeyImplementer<K1, K2>
其中类型参数K1, K2
是K
的子类型(包括) - 即它们的上限由类型参数
K
决定。由CompositeKeyBasedCreditCardDetailsHolder
定义
请注意 K1, K2
的类型参数不限于同一类型。例如:这是可能的:
// note the arguments for K1, K2. Both extend Number
CompositeKeyImplementer<Integer, Double> cki =
new CompositeKeyImplementer<Integer, Double>();
// note the argument for K is Number
CompositeKeyBasedCreditCardDetailsHolder<Number, String> cdh =
new CompositeKeyBasedCreditCardDetailsHolder<Number, String>(cki);
我建议(重新)阅读 the java tutorials在通配符上,也可能 Angelika Langer on wildcard type arguments因为他们有很多关于通配符用途和使用方式的信息。
关于具有复合键和通配符的 Java 泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28253016/