这确实是一个尴尬的情况,这是由于通配符捕获的限制以及 from 的返回类型不太理想D.getObject
。
有一些解决方法,但没有一个是漂亮的。第一种是简单地进行未经检查的演员表:
@SuppressWarnings("unchecked") //it's okay for the two captures not to match
Callback<B<String, ?>, C<String, ?>> result =
(Callback<B<String, ?>, C<String, ?>>)instance.method();
编辑:一些编译器(更正确地)需要通过以下方式进行双重转换Callback<?, ?>
:
@SuppressWarnings("unchecked") //it's okay for the two captures not to match
Callback<B<String, ?>, C<String, ?>> result =
(Callback<B<String, ?>, C<String, ?>>)(Callback<?, ?>)instance.method();
您还可以使用辅助方法 - 这是通配符捕获问题的常见解决方案:
static <T> void helper(A<String, T> a) {
Callback<B<String, T>, C<String, T>> result = a.method();
//logic
}
...
helper(instance);
更新:
实际上,您可以将这两种方法结合起来,至少将丑陋隔离到一个辅助方法中:
static <S, T> Callback<B<S, ?>, C<S, ?>> disentangleCallback(
Callback<B<S, T>, C<S, T>> callback
) {
@SuppressWarnings("unchecked") //it's okay for the two captures not to match
final Callback<B<S, ?>, C<S, ?>> withWidenedTypes =
(Callback<B<S, ?>, C<S, ?>>)(Callback<?, ?>)callback;
return withWidenedTypes;
}
然后像这样使用它:
Callback<B<String, ?>, C<String, ?>> result =
disentangleCallback(instance.method());
或者一个类似的方法,它简单地接受一个并通过调用自身A<S, T>
返回一个,然后强制转换。Callback<B<S, ?>, C<S, ?>>
method
另一个想法:如果第二个类型参数 ofA
总是未知的,那么删除它并扩大返回类型可能会更容易method
:
class A<S> {
public Callback<B<S, ?>, C<S, ?>> method() { ... }
}
T
我意识到这将是一个不幸的让步,但如果它从来没有真正有用是有道理的。