如何在Java中提示两类型参数为同一类型?AOSP请求复制问题
这个问题的核心是Java泛型的通配符捕获不匹配:当你遍历CaptureRequest.Key<?>时,编译器把每个key的类型视为独立的捕获变量(比如CAP#1),而request.get(key)返回的是另一个独立的捕获变量CAP#2——编译器无法证明这两个捕获变量是同一个类型,所以builder.set(key, request.get(key))会报错,因为set方法要求Key<T>和T类型严格匹配。
你的辅助函数思路是对的,但拆分得太细反而破坏了泛型类型的关联性。正确的做法是把获取值和设置值放在同一个泛型方法里,让编译器在单个方法上下文里明确T的统一类型。
正确实现代码
// 把复制逻辑封装到单个泛型方法中 private static <T> void copyRequestKey(CaptureRequest.Builder builder, CaptureRequest request, CaptureRequest.Key<T> key) { T value = request.get(key); builder.set(key, value); } // 调用方式 for (CaptureRequest.Key<?> key : request.getKeys()) { // 这里通过通配符捕获,让编译器把key的类型绑定到泛型T上 copyRequestKey(builder, request, key); }
为什么这样能解决问题?
当你在for循环中传入CaptureRequest.Key<?>到copyRequestKey方法时,编译器会对每个key进行通配符捕获:它会为当前循环的key生成一个具体的类型变量T,同时保证request.get(key)返回的T和builder.set需要的T是同一个类型——整个方法上下文里T是统一的,没有类型不匹配的问题。
针对你的特殊场景补充
因为你是在库中生成影子请求,无法访问原始builder,这个方案完全适用:只需要传入现有CaptureRequest实例和新创建的CaptureRequest.Builder实例,就能完整复制所有键值对,不需要依赖任何原始构建逻辑。
另外,如果你担心某些键值对存在类型安全风险(理论上AOSP的CaptureRequest不会出现这种情况),可以在方法中添加类型检查,但通常不需要——因为request.get(key)的返回类型肯定和Key<T>的T匹配,这是CaptureRequest本身的API契约保证的。
内容的提问来源于stack exchange,提问作者LB2




