我无法为方法的输出声明一个完全通用的类型。 情况如下:
class A<S,T>{
public Callback<B<S,T>,C<S,T>> method();
}
在我的代码中我有其中一个;
A<String, ?> instance;
然而,当我打电话
result = instance.method()
使编译器满意的唯一方法是声明
Callback<?, ?> result = instance.method()
但我真的希望对我的仿制药更具体,并宣布
Callback<B<String, ?>,C<String, ?>> result = instance.method()
但是,由于每个通配符都是独立的,编译器会抱怨这是不正确的,声明它无法从
转换Callback<B<String,capture#3-of ?>,C<String,capture#3-of ?>>
有没有办法正确宣布这种情况?
仅供参考,A,B和C类来自外部库。 我试图将我的实例声明为
A<String, Object>
但它也是我无法控制的第四类方法的结果:
class D<T>{
public A<T, ?> getObject();
}
D<String> start = new D<String>();
A<String, ?> = start.getObject();
...
答案 0 :(得分:1)
你可以
Callback<? extends B<String, ?>, ? extends C<String, ?>> result
= instance.method();
答案 1 :(得分:1)
这确实是一个尴尬的情况,是由于通配符捕获的限制以及来自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
,然后进行投射。
另一个想法:如果A
的第二个类型参数总是是未知的,那么删除它并扩大method
的返回类型可能更容易:< / p>
class A<S> {
public Callback<B<S, ?>, C<S, ?>> method() { ... }
}
我意识到这将是一个不幸的让步,但如果T
从未真正有用,那就有意义了。