通用生产者和消费者

圣安东尼奥

我正在设计一个容器类,旨在容纳一对实现

public interface MetaData<ValueType>{
    public String getName();
}

以及ValueTypeType参数的相应值所以我写了这个(省略了一些不变量):

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章