Note that there are some explanatory texts on larger screens.

plurals
  1. POgeneric super argument
    text
    copied!<p>Can anybody explain why the following code doesn't compile, and if there is anyway to write the doubleRequestExecute with the desired behavior (being able to pass in a <code>Callback&lt;Pair&lt;? super A, ? super B&gt;&gt;)</code> function that will actually work?</p> <pre><code>public class Example { public interface Callback&lt;T&gt; { void onSuccess(T result); void onFailure(Throwable caught); } public interface Entity {} public static class Request&lt;T extends Entity&gt; { public void execute(Callback&lt;? super T&gt; callback) { /* In real code, get a T somewhere and pass it to onSuccess */ callback.onSuccess(null); } } public static class Holder&lt;T&gt; { public T value; } public static class Pair&lt;A, B&gt; { public Pair(A first, B second) { this.first = first; this.second = second; } public final A first; public final B second; } public static &lt;A extends Entity, B extends Entity, C super A, D super B&gt; void doubleRequestExecute(Request&lt;A&gt; request1, Request&lt;B&gt; request2, final Callback&lt;Pair&lt;C, D&gt;&gt; callback) { final Holder&lt;A&gt; result1 = new Holder&lt;&gt;(); final Holder&lt;B&gt; result2 = new Holder&lt;&gt;(); request1.execute(new Callback&lt;A&gt;() { @Override public void onSuccess(A result) { if (result2.value != null) { callback.onSuccess(new Pair&lt;C, D&gt;(result, result2.value)); } else { result1.value = result; } } @Override public void onFailure(Throwable caught) { callback.onFailure(caught); } }); request2.execute(new Callback&lt;B&gt;() { @Override public void onSuccess(B result) { if (result1.value != null) { callback.onSuccess(new Pair&lt;C, D&gt;(result1.value, result)); } else { result2.value = result; } } @Override public void onFailure(Throwable caught) { callback.onFailure(caught); } }); } } </code></pre> <p>If I simply switch the callback argument to <code>Callback&lt;Pair&lt;A, B&gt;&gt;</code> it works fine, but it is overly restrictive on the callback types that can be used.</p> <p>Here is the compile error I get when I try to build the above code:</p> <pre><code>Main.java:27: error: &gt; expected public static &lt;A extends Entity, B extends Entity, C super A, D super B&gt; ^ Main.java:27: error: illegal start of type public static &lt;A extends Entity, B extends Entity, C super A, D super B&gt; ^ Main.java:27: error: '(' expected public static &lt;A extends Entity, B extends Entity, C super A, D super B&gt; ^ Main.java:27: error: &lt;identifier&gt; expected public static &lt;A extends Entity, B extends Entity, C super A, D super B&gt; ^ Main.java:27: error: &lt;identifier&gt; expected public static &lt;A extends Entity, B extends Entity, C super A, D super B&gt; ^ 5 errors </code></pre> <p>Example desired use:</p> <pre><code>doubleRequestExecute(new Request&lt;Entity&gt;(), new Request&lt;Entity&gt;(), new Callback&lt;Pair&lt;Object, Object&gt;&gt;() { @Override onSuccess(Pair&lt;Object, Object&gt; result) {} @Oberride onFailure(Throwable caught) {} }); </code></pre> <p>Also note that in the actual code, all the handlers are executed on the same thread, so the obvious ToCToU race condition isn't an issue (for a more general approach, one could create an atomic boolean and simply use compareAndSet to check if the other request has completed).</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload