在“Foo”类完成了预期之后,一个对象的映射具有关于键和值类型之间关系的“一些控制”。
import java.util.Map;
public class Foo {
interface FooKey<T> {}
enum IntFooKey implements FooKey<Integer> {
Int1,
Int2
}
enum StringFooKey implements FooKey<String> {
S1,
S2
}
Map<FooKey<?>,Object> data;
public <T> T get( FooKey<T> k ) {
return (T)data.get(k); // ugly warning
}
public <T> void put( FooKey<T> k, T v ) {
data.put(k,v);
}
public void test() {
Integer x = 1;
put( IntFooKey.Int1, x );
x = get( IntFooKey.Int1 );
String s = null;
put( IntFooKey.Int2, s ); // COMPILATION ERROR, OK
s = get( IntFooKey.Int2 ); // COMPILATION ERROR, OK
}
}
a)第一个问题是,为了改进代码,可以替换:
Map<FooKey<?>,Object> data;
通过以下方式:
Map<FooKey<T>,T> data;
b)第二个问题是:某种方式可以使用单个枚举的可能键,而不是每个可能类型的值的一个枚举?类似的东西:
enum FooKeys {
Int1<Integer>,
Int2<Integer>,
S1<String>,
S2<String>
}
c)欢迎任何与此代码相关的其他建议。
感谢。
答案 0 :(得分:1)
不幸的是,Java的类型系统不够复杂,无法表示地图的实际类型。为此,您需要提供一个类型等式,显示键和值类型是如何相关的,而Java没有这样的语法。
所以你能做到的最好就是像你在这里一样投入到T中。如果需要,您可以添加@SuppressWarnings("unchecked")
以使警告消失。
如果需要,您可以抑制一行,如下所示:
public <T> T get(FooKey<T> k) {
@SuppressWarnings("unchecked")
T value = (T) data.get(k);
return value;
}
从根本上说,Map<FooKey<T>, T>
不能是您想要的类型,因为这会限制地图只包含单个类型的值T。