繁体   English   中英

当类型是通配符时,如何将通用结果用作通用参数?

[英]How to use a generic result as a generic parameter when the type is a wildcard?

[更新]真实情况比我最初提出的问题要复杂一些。 我已经改变了一些代码来反映这一点。[/ UPDATE]

我对以下行为感到有点难过。 给出如下代码:

interface Inter<T> {
  T makeT();
  void useT(T t);
}

public class Foo {
  public void bar(Qux q) {
    Inter<?> x = getInterForQux(q);
    x.useT(x.makeT());
  }

  Inter<?> getInterForQux(Qux q) {
    if( someTest(q) ) {
      return (Inter<Integer>) mkAnInterInt();
    } else {
      return (Inter<Double>) mkAnInterDouble();
    }
  }
}

Javac给了我错误:

Inter <capture#478 of?>中的useT(捕获#478?)无法应用于(java.lang.Object)

而Eclipse给了我:

Inter <capture#1-of?>类型中的方法useT(捕获#1-of?)不适用于参数(捕获#2-of?)

显然,不管是什么T的结果是类型makeT()相同的参数类型的useT() 为什么我不能这样做? 有解决方法吗?

当您使用通配符,编译器无法看到的返回类型x.makeT()和参数类型x.useT()是相同的。 为了保证它们是相同的,你应该在这里使用泛型方法:

public class Foo { 
    public <T> void bar(Inter<T> x) { 
        x.useT(x.makeT()); 
    } 
} 

这是合乎逻辑的,因为Inter<?>.makeT()可以返回任何内容,而Inter<?>.useT(..)会消耗任何东西,但两个任何东西都可以不同。

那会解决它:

public <T> void bar(Inter<T> x) {
    x.useT(x.makeT());
}

使用捕获助手:

public void bar(Qux q) {
    Inter<?> x = getInterForQux(q);
    barPrivate(x);
}
private <T> void barPrivate(Inter<T> x) {
    x.useT(x.makeT());
}

这为您提供了相同的bar签名

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM