Java泛型:推断和引用类的实例化使用的类
由于密钥持有者接口,比如以下:Java泛型:推断和引用类的实例化使用的类
public interface KeyHolder<K extends Key> {
K getKey();
}
我想创建这样一个类:
public KeyHolderSet<H extends KeyHolder<K extends Key>> extends HashSet<H> {
public Set<K> getKeySet() {
Set<K> keySet = new HashSet<K>();
for (H keyHolder : this) {
keySet.add(keyHolder.getKey());
}
return keySet;
}
}
但是,这是行不通的,我能得到的最接近的是:
public KeyHolderSet<H extends KeyHolder<? extends Key>> extends HashSet<H> {
public <K extends Key> Set<K> getKeySet() {
Set<K> keySet = new HashSet<K>();
for (H keyHolder : this) {
// Explicit cast to K
keySet.add((K)keyHolder.getKey());
}
return keySet;
}
}
任何方法都可以解决这个问题吗?
你需要把它写这样的:
public KeyHolderSet<K extends Key, H extends KeyHolder<K>> extends HashSet<H> {
public Set<K> getKeySet() {
...
}
}
不幸的是,你必须首先声明K的类型,它无法推断。
也许
public class KeyHolderSet<K extends Key, H extends KeyHolder<K>> extends
HashSet<H> {
public Set<K> getKeySet() {
...
}
}
,如果你不介意的参数化KeyHolderSet两次。
假设实现类存储在一组密钥持有者并不重要,你可以尝试这样的事:
public class KeyHolderSet<K extends Key> extends HashSet<KeyHolder<K>> {
public Set<K> getKeySet() {
...
}
}
谢谢塞巴斯蒂安。不幸的是,在我的情况下,KeyHolder的实现很重要,但希望这种解决方案可以为其他人服务。 – Zecrates 2011-06-09 05:15:57
鉴于KeyHolder<K extends Key>
似乎没有必要使用KeyHolderSet<H extends KeyHolder<K extends Key>>
只是坚持:
public class KeyHolderSet<H extends KeyHolder<?>>
你应该没问题。
编辑:我看到你的问题getKeySet()
。这个方法应该返回H而不是K. H将被输入你在KeyHolderSet(变量,而不是类)声明中输入的内容。
public class KeyHolderSet<H extends KeyHolder<?>> extends HashSet<H> {
private H theKeySet;
public void setKeySet(H keyset) {
theKeySet = keyset;
}
public H getKeySet() {
return theKeySet;
}
}
-
class betterKey extends Key {
}
-
public static void main(String[] args) {
KeyHolder<betterKey> kh = new KeyHolder<betterKey>() {
};
KeyHolderSet<KeyHolder<betterKey>> khs = new KeyHolderSet<KeyHolder<betterKey>>();
khs.setKeySet(kh);
KeyHolder<Key> kh2 = khs.getKeySet(); // Type mismatch
}
正如你可以看到khs.getKeySet()
回报KeyHolder<betterKey>
预期。
EDIT2: 你可以建立起来的一套KeyHolderSet类的外部:
public static void main(String[] args) {
KeyHolderSet<KeyHolder<betterKey>> khs = new KeyHolderSet<KeyHolder<betterKey>>();
Set<betterKey> bks = new HashSet<betterKey>();
for (KeyHolder<betterKey> kh : khs) {
bks.add(kh.getKey());
}
}
一个替代的解决方案,我想出了返回一个完全通用的设置,记住所有类型检查会丢失这种方式。
public class KeyHolderSet<H extends KeyHolder<?>> extends HashSet<H> {
public <K extends Key> Set<K> getKeySet() {
Set<K> s = new HashSet<K>();
for (H keyHolder : this) {
s.add((K) keyHolder.getKey()); // Unchecked cast
}
return s;
}
public static void main(String[] args) {
KeyHolderSet<KeyHolder<betterKey>> khs = new KeyHolderSet<KeyHolder<betterKey>>();
Set<Key> ks = khs.getKeySet(); // No problem
Set<betterKey> bks = khs.getKeySet(); // No problem
Set<evenBetterKey> ss = khs.getKeySet(); // No problem
}
}
class betterKey implements Key {
}
class evenBetterKey extends betterKey {
}
嗨Dorus。也许意图不明确。我不希望getKeySet返回一个KeyHolder,我期望它返回一个Set
我唯一能想到的就是返回Set
我意识到返回一个'Set
AARGH,是的,我应该补充说,作为另一种选择,但它是令人眼花缭乱的痛苦必须单独申报重点:( – Zecrates 2011-06-08 16:48:43
另一种选择是使用通配符界('?延伸...' ),但你最终会添加禁止警告,以检查未经检查的转换... – Finbarr 2011-06-08 22:57:18
嗨Finbarr,请你提供一个例子,你的意思是使用有界通配符吗?它不同于我的第二个解决方案吗? – Zecrates 2011-06-09 05:17:11