2

我无法正确使用 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());

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

4

1 回答 1

0

在大多数情况下它是正确的,但是您需要在实例化过程中指定 <...> 部分(否则它将默认为原始类型,类似于 <Object>。有关原始、< ? > 和 <对象>)。Foo 和 Bar 都是对象,所以编译器看到这个并认为没关系。

Here is what the instantiation looks like using <...>. Here, InterfaceXYZ<Foo> and FooImplementation are interchangeable (as the compiler knows FooImplementation is a InterfaceXYZ<Foo>)

For Foo

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

And for Bar (getting compile time error instead of runtime)

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

Additional note:

InterfaceXYZ<?> fi = new FooImplementation(); won't throw a compile time error because you might say add fi to a List<InterfaceXYZ<?>>, where InterfaceXYZ<bar> is also valid and usable. The compiler can't and won't check for every possible way an object can be used in the call stack, so only trust compile time errors to appear under just the context of the current class being compiled.

于 2017-05-10T20:49:55.920 回答