任何人都可以解释为什么以下代码无法编译,以及是否有任何方式编写具有所需行为的 doubleRequestExecute (能够传入一个Callback<Pair<? super A, ? super B>>)
实际工作的函数?
public class Example {
public interface Callback<T> {
void onSuccess(T result);
void onFailure(Throwable caught);
}
public interface Entity {}
public static class Request<T extends Entity> {
public void execute(Callback<? super T> callback) {
/* In real code, get a T somewhere and pass it to onSuccess */
callback.onSuccess(null);
}
}
public static class Holder<T> {
public T value;
}
public static class Pair<A, B> {
public Pair(A first, B second) {
this.first = first;
this.second = second;
}
public final A first;
public final B second;
}
public static <A extends Entity, B extends Entity, C super A, D super B>
void doubleRequestExecute(Request<A> request1, Request<B> request2,
final Callback<Pair<C, D>> callback) {
final Holder<A> result1 = new Holder<>();
final Holder<B> result2 = new Holder<>();
request1.execute(new Callback<A>() {
@Override public void onSuccess(A result) {
if (result2.value != null) {
callback.onSuccess(new Pair<C, D>(result, result2.value));
} else {
result1.value = result;
}
}
@Override public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
});
request2.execute(new Callback<B>() {
@Override public void onSuccess(B result) {
if (result1.value != null) {
callback.onSuccess(new Pair<C, D>(result1.value, result));
} else {
result2.value = result;
}
}
@Override public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
});
}
}
如果我只是将回调参数切换到Callback<Pair<A, B>>
它可以正常工作,但它对可以使用的回调类型过于限制。
这是我尝试构建上述代码时遇到的编译错误:
Main.java:27: error: > expected
public static <A extends Entity, B extends Entity, C super A, D super B>
^
Main.java:27: error: illegal start of type
public static <A extends Entity, B extends Entity, C super A, D super B>
^
Main.java:27: error: '(' expected
public static <A extends Entity, B extends Entity, C super A, D super B>
^
Main.java:27: error: <identifier> expected
public static <A extends Entity, B extends Entity, C super A, D super B>
^
Main.java:27: error: <identifier> expected
public static <A extends Entity, B extends Entity, C super A, D super B>
^
5 errors
示例所需用途:
doubleRequestExecute(new Request<Entity>(), new Request<Entity>(),
new Callback<Pair<Object, Object>>() {
@Override onSuccess(Pair<Object, Object> result) {}
@Oberride onFailure(Throwable caught) {}
});
另请注意,在实际代码中,所有处理程序都在同一个线程上执行,因此明显的 ToCToU 竞争条件不是问题(对于更通用的方法,可以创建一个原子布尔值并简单地使用 compareAndSet 来检查其他请求已完成)。