次のコードがコンパイルされない理由を誰かが説明できます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 を使用して、他の要求が完了しました)。