嵌套类型无法推断类型变量T:Java代码methodB调用报错咨询
我来帮你拆解这个类型推断报错的问题,其实根源在于methodB的方法签名和你在methodA里传入的参数类型不匹配,编译器没办法自动关联嵌套的泛型类型。
问题原因
先看methodB的方法签名:
private <T> CompletableFuture<Bar<T>> methodB(Foo request, Function<Foo, Bar<T>> mapper, CompletableFuture<Bar<T>> callback)
它的第三个参数要求是CompletableFuture<Bar<T>>,但你在methodA里传入的是CompletableFuture<InputStream>——这两个参数的泛型完全不对等:一个是被Bar包裹的类型,一个是原始的InputStream。
Java的类型推断系统没办法自动把InputStream映射到Bar<T>里的T,因为第三个参数的泛型直接是Bar<T>,而你传入的是没有被Bar包裹的InputStream,编译器找不到T的对应关系,就会抛出“无法推断嵌套类型的类型变量T”的错误。
解决方法
根据你的实际需求,有几种可行的修复方案:
方案1:修正methodB的方法签名(最可能的正确做法)
如果methodB的第三个参数本来就应该接收原始类型的CompletableFuture<T>(而不是CompletableFuture<Bar<T>>),那修改签名就能直接解决问题:
private <T> CompletableFuture<Bar<T>> methodB(Foo request, Function<Foo, Bar<T>> mapper, CompletableFuture<T> callback) { // 你的业务逻辑实现 return null; }
修改后,编译器能自动推断出T是InputStream:callback是CompletableFuture<InputStream>,mapper返回Bar<InputStream>,类型完全匹配。
方案2:在methodA中包装传入的callback
如果methodB的签名是正确的,那你需要把CompletableFuture<InputStream>转换成CompletableFuture<Bar<InputStream>>,也就是把InputStream用Bar包裹起来:
public CompletableFuture<Bar<InputStream>> methodA(CompletableFuture<InputStream> callback) { // 将InputStream包装为Bar<InputStream> CompletableFuture<Bar<InputStream>> wrappedCallback = callback.thenApply(this::mapper); return methodB(new Foo(), this::mapper, wrappedCallback); }
这里用thenApply方法把callback的结果转换成Bar<InputStream>,这样传入methodB的参数类型就完全匹配了。
方案3:显式指定类型变量(治标不治本,不推荐)
如果你暂时不想修改签名或包装参数,可以在调用methodB时显式指定T的类型,强制告诉编译器T是InputStream:
public CompletableFuture<Bar<InputStream>> methodA(CompletableFuture<InputStream> callback) { // 显式指定泛型参数<InputStream> return this.<InputStream>methodB(new Foo(), this::mapper, callback); }
不过这种方法只是绕过了类型推断的问题,本质上callback的类型还是和methodB的参数不兼容,所以只适合临时调试,不推荐作为最终解决方案。
内容的提问来源于stack exchange,提问作者ryber

