如何在Java中提示两个类型参数实际上是同一类型



我正在使用AOSP的CaptureRequest及其相关的CaptureRequest.Builder类,并且需要将设置键值从CaptureRequest的现有实例复制到CaptureRequest.Builder1的新实例。

我想要运行的基本代码如下:

for(CaptureRequest.Key<?> key : request.getKeys()) {
builder.set(key, request.get(key));
}

其中CaptureRequest.Builder.set()函数定义为<T> void set(Key<T> key, T value)CaptureRequest.get()定义为<T> T get(Key<T> key)。但这使得编译器barf出现以下错误:

Source.java:2: error: method set in class Builder cannot be applied to given types;
builder.set(key, request.get(key));
^
required: Key<T>,T
found: Key<CAP#1>,CAP#2
reason: inferred type does not conform to lower bound(s)
inferred: CAP#1
lower bound(s): Object
where T is a type-variable:
T extends Object declared in method <T>set(Key<T>,T)
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends Object from capture of ?
CAP#2 extends Object from capture of ?

如果我正确地解释了这个错误,它试图说它不能将两个函数的<T>s关联为同一个T。因此,为了提示它是相同的T,我创建了一些辅助函数,这些函数应该可以清楚地表明它是同一个T,所以我有了这个:

private static <T> T getKeyValue(CaptureRequest request, CaptureRequest.Key<T> key) {
return (T)request.<T>get(key);
}
private static <T> void setKeyValue(CaptureRequest.Builder builder, CaptureRequest.Key<T> key) {
builder.<T>set(key, (T)MyClass.<T>getKeyValue(key));
}
.....
for(CaptureRequest.Key<?> key : request.getKeys()) {
setKeyValue(builder, key);
}

这无法使Java编译器平静下来,它抛出了与前一个非常相似的错误:

Source.java:6: error: method getKeyValue in class MyClass cannot be applied to given types;
builder.<T>set(key, (T)MyClass.<T>getKeyValue(key));
^
required: CaptureRequest,Key<T#1>
found: Key<T#2>
reason: actual and formal argument lists differ in length
where T#1,T#2 are type-variables:
T#1 extends Object declared in method <T#1>getKeyValue(CaptureRequest,Key<T#1>)
T#2 extends Object declared in method <T#2>setKeyValue(Builder,Key<T#2>)

我如何才能以理智的方式执行键值的复制?


1是的,我知道这很奇怪,而且与API的典型使用有点倒退,因此;不寻常";。上下文是,已经构建的请求(超出了库的范围(正在渗透到一个库中,该库需要用自己的请求进行影子处理,主要是模仿原始请求,但略有修改,并且所述库无法访问原始构建器来构建影子同级请求。是的,这很奇怪,超出了这个问题的范围。这个问题实际上是关于Java的模板方法和明显的编译错误。

为什么不只是:

builder.set((CaptureRequest.Key<Object>)key, request.get(key));

很确定它应该起作用。

最新更新