我正在设计一个容器类,旨在容纳一对实现
public interface MetaData<ValueType>{
public String getName();
}
以及ValueType
Type参数的相应值。所以我写了这个(省略了一些不变量):
public final class ParametersImpl implements Parameters{
private final Map<MetaData<?>, Object> parameters;
{
parameters = new HashMap<>();
}
@Override
public Object getValue(MetaData<?> pmd) {
return parameters.get(pmd);
}
@Override
public <M> void put(MetaData<M> p, M value) {
parameters.put(p, value);
}
}
在哪里
public interface Parameters {
public Object getValue(MetaData<?> pmd);
public <M> void put(MetaData<M> p, M value);
}
问题是当客户调用方法时,Object getValue(MetaData<?> pmd)
他们必须进行显式转换:
MetaData<List<Integer>> metaData;
Paramters params;
List<Integer> list= new ArrayList<>();
//intialization
params.put(metaData, list);
//do some other
List<Integer> lst = (List<Integer>) params.getValue(metaData);
尽管强制转换是完全安全的,但我还是想避免使用它,并提供某种通用方法。但是当我尝试这个声明时:
public <M> M getValue(MetaData<M> pmd);
我在实现中遇到编译错误:
public <M> M getValue(MetaData<M> pmd) {
return parameters.get(pmd); //cannot convert capture-of-#1 to M
}
问题:是否有任何方法可以泛化该方法public Object getValue(MetaData<?> pmd);
?
您只需要强制转换从地图检索的值:
public <M> M getValue(MetaData<M> pmd) {
return (M) parameters.get(pmd);
}
但是在这一点上,编译器抱怨它无法检查演员表。这是什么意思?好吧,用Java源代码进行的常规转换是用(SomeType) val
-表示的-编译器检查该操作是否完全不合法(例如,您不能转换对的String
引用Integer
),并发出在运行时执行的字节码,可能会抛出该错误一个ClassCastException
。
当使用类型变量强制转换引用时,编译器无法发出这样的字节码,因为类型变量在运行时不存在-因此会发出编译警告。你应该:
@SuppressWarnings("unchecked")
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句