Java泛型捕获组

时间:2017-05-10 20:30:25

标签: java generics nested-generics

我无法正确使用Java捕获组。

假设我有这些课程:

class Foo{}
class Bar{}

interface InterfaceXYZ<T>{ 
  void doSomething(T t);
}

class FooImplementation implements InterfaceXYZ<Foo>{
  @Override void doSomething(Foo){}
}

最后,

class Delegator<T>{
  Delegator(InterfaceXYZ<T> delegate){this.delegate = delegate;}

  void doSomething(T t) {
    delegate.doSomething(t);
  }

  private InterfaceXYZ<T> delegate;
}

问题是这很好用 -

FooImplementation fi = new FooImplementation();
Delegator d = new Delegator(fi);
d.doSomething(new Foo());

这不能正常工作(如预期的那样) - 导致运行时异常

FooImplementation fi = new FooImplementation();
Delegator d = new Delegator(fi);
d.doSomething(new Bar());

为什么不抛出编译时错误?如果我必须使它抛出编译时错误,我需要做出哪些更改?

1 个答案:

答案 0 :(得分:0)

在大多数情况下,它是正确的,但您需要指定&lt; ...&gt;实例化期间的部分(或者它将默认为原始类型,类似于&lt; Object&gt;。有关raw,&lt;?&gt;和&lt; Object&gt;)之间差异的详细信息,请参阅this answer。而Foo和Bar都是对象,所以编译器会看到它并认为它没问题。

以下是使用&lt; ...&gt;实例化的内容。这里,InterfaceXYZ<Foo>和FooImplementation是可以互换的(因为编译器知道FooImplementation是InterfaceXYZ<Foo>

对于Foo

InterfaceXYZ<Foo> fi = new FooImplementation();
Delegator<Foo> d = new Delegator<Foo>(fi);
d.doSomething(new Foo());

对于Bar(获取编译时错误而不是运行时)

InterfaceXYZ<Bar> fi = new FooImplementation();
Delegator<Bar> d = new Delegator<Bar>(fi);
d.doSomething(new Bar());

附加说明:

InterfaceXYZ<?> fi = new FooImplementation();不会抛出编译时错误,因为您可能会将{fi}添加到List<InterfaceXYZ<?>>,其中InterfaceXYZ<bar>也是有效且可用的。编译器无法检查对象在调用堆栈中的每种可能方式,因此只能将编译时错误信息显示在正在编译的当前类的上下文中。