Java 泛型超参数
有人能解释一下为什么下面的代码没有编译,以及是否有编写doubleRequestExecute所需的行为(能够在Java 泛型超参数,java,generics,super,Java,Generics,Super,有人能解释一下为什么下面的代码没有编译,以及是否有编写doubleRequestExecute所需的行为(能够在CallbackFirst尝试中传递)的方法吗 (不起作用,请参见备注) 试着这样做: public static <A extends Entity, B extends Entity> void doubleRequestExecute(Request<A> request1, Request<B> request2, final
CallbackFirst尝试中传递)的方法吗
(不起作用,请参见备注)
试着这样做:
public static <A extends Entity, B extends Entity>
void doubleRequestExecute(Request<A> request1, Request<B> request2,
final Callback<Pair<? super A, ? super B>> callback)
...
callback.onSuccess(new Pair<A, B>(result, result2.value));
...
如何实例化l
?它是一个列表,由整数
限定的内容组成
List<List<? super Integer>> l = new ArrayList<List<Integer>>(); // NO
List<List<? super Integer>> l = new ArrayList<List<Number>>(); // NOPE
List<List<? super Integer>> l = new ArrayList<List<Object>>(); // NEITHER
List<List<? super Integer>> l = new ArrayList<List<? super Integer>>(); // OK
List那么,您正在尝试实现一个工作流join。您希望将一个成对的延续转换为两个组件的延续。我认为在您的实现中存在竞争条件,但暂且不谈,让我们谈谈类型
如果您死心塌地地想让组件类型具有名称,并且与A
和B
不同,那么它们需要是它们的超类(因为您将从各自的请求中获得A和B)。这是您在OP中尝试的。假设C
和D
只能是实体
,将关系扭转过来,您可以在不允许使用super
关键字的情况下获得它:
public static < C extends Entity, D extends Entity, A extends C, B extends D > void doubleRequestExecute(
Request< A > request1, Request< B > request2,
Callback< Pair< C, D > > callback
) {
...
}
如果您愿意使用这样的调用代码(我相信这是模仿@Flavio的回答的):
尤里卡
Java中没有声明时间差异声明这一事实意味着像这样深度嵌套的泛型类型会带来无尽的麻烦。解决方案是使用愚蠢的包装类来强制继承工作
public static class PairCallback< A, B > implements Callback< Pair< A, B > > {
private final Callback< Pair< A, B > > cbDelegate;
public PairCallback( Callback< Pair< A, B > > cbDelegate ) {
this.cbDelegate = cbDelegate;
}
public void onSuccess( A a, B b ) {
onSuccess( new Pair< A, B >( a, b ) );
}
@Override public void onSuccess( Pair< A, B > p ) { cbDelegate.onSuccess( p ); }
@Override public void onFailure( Throwable caught ) { cbDelegate.onFailure( caught ); }
}
public static < A extends Entity, B extends Entity > void doubleRequestExecute(
Request< A > reqA, Request< B > reqB,
final PairCallback< ? super A, ? super B > callback
) {
final Holder< A > result1 = new Holder< A >();
final Holder< B > result2 = new Holder< B >();
reqA.execute(new Callback<A>() {
@Override public void onSuccess(A result) {
if (result2.value != null) {
callback.onSuccess(result, result2.value);
} else {
result1.value = result;
}
}
@Override public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
});
reqB.execute(new Callback<B>() {
@Override public void onSuccess(B result) {
if (result1.value != null) {
callback.onSuccess(result1.value, result);
} else {
result2.value = result;
}
}
@Override public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
});
}
private static class Entity1 extends Entity {}
private static class Entity2 extends Entity1 {}
public static void main( String... args ) {
doubleRequestExecute(
new Request< Entity >(), new Request< Entity >(),
new PairCallback< Object, Object >( new Callback< Pair< Object, Object > >() {
@Override public void onSuccess( Pair< Object, Object> result ) {}
@Override public void onFailure( Throwable caught ) {}
} )
);
doubleRequestExecute(
new Request< Entity2 >(), new Request< Entity1 >(),
new PairCallback< Entity1, Entity >( new Callback< Pair< Entity1, Entity > >() {
@Override public void onSuccess( Pair< Entity1, Entity > result ) {}
@Override public void onFailure( Throwable caught ) {}
} )
);
}
公共静态类PairCallback实现回调>{
私有最终回调>cbDelegate;
公共对回调(回调>cbDelegate){
this.cbDelegate=cbDelegate;
}
成功时公开作废(A、B){
成功(新对(A,B));
}
@在成功时重写公共void(对p){cbDelegate.onSuccess(p);}
@重写公共void onFailure(可丢弃捕获){cbDelegate.onFailure(捕获);}
}
公共静态无效doubleRequestExecute(
请求reqA,请求reqB,
最终配对回拨<?超级A,?超级B>回拨
) {
最终持有人结果1=新持有人();
最终持有人结果2=新持有人();
请求执行(新回调(){
@成功时覆盖公共无效(结果){
if(result2.value!=null){
onSuccess(result,result2.value);
}否则{
结果1.value=结果;
}
}
@失效时覆盖公共无效(可丢弃){
callback.onFailure(捕获);
}
});
要求执行(新回调(){
@成功时覆盖公共无效(B结果){
如果(result1.value!=null){
onSuccess(result1.value,result);
}否则{
结果2.值=结果;
}
}
@失效时覆盖公共无效(可丢弃){
callback.onFailure(捕获);
}
});
}
私有静态类Entity1扩展了实体{}
私有静态类Entity2扩展了Entity1{}
公共静态void main(字符串…参数){
双重请求执行(
新请求<实体>(),新请求<实体>(),
新的PairCallback
我将投票表决你的问题,因为它是多么具有挑战性和相关性。类型参数没有下限。事实上-只有通配符可以使用super
。明白为什么吗?我知道在大多数情况下,这根本没有用(由于任何东西都可能衰变为超越一切的物体,因此可能使用得非常错误),但在这种情况下,它似乎有一个有效的用途,而且由于任意的语言限制,根本不可能做我想做的事情。我很好奇为什么这个问题被否决了。在我看来,这是一个完全合理的做法,而语言似乎不支持它(或者至少还没有人提供有效的方法)。这是我尝试的第一件事,但很快就失败了。调用时,编译失败,出现以下错误没有类型变量的实例A,B的存在使得参数类型符合形式参数类型CallbackFurthermore,即使它超过了这一点,Pair
也无法转换为pairy。你是对的,我做了一些更正。不过,不要问我为什么它会起作用,我不能完全理解这一点。不幸的是,它仍然不起作用,目标是得到Callback我想我正在做你需要的:Pair
不可分配给Pair
,就像List
不可分配给List
,所以你不能为Pair
实例提供回调
。答案更新。至于线程安全,实际的代码保证所有处理程序都是安全的在同一个线程上执行,因此没有竞争(应该提到)。不幸的是,这两种解决方案都不充分。第一种解决方案,除了没有真正解决手头的问题之外,甚至不可能,因为类型为?super Pair的对象不可能被实例化(它仍然需要A和B,而不是任何超级对象).第二个解决方案很接近,但C和D不一定需要扩展实体(只需要请求类型参数),例如Callbackpublic static <A extends Entity, B extends Entity> void doubleRequestExecute(Request<A> request1, Request<B> request2,
final Callback<? super Pair<? extends A, ? extends B>> callback) { ... }
private static final class E1 extends Entity { }
private static final class E2 extends Entity { }
public static void main(String[] args) {
Request<E1> r1 = null;
Request<E2> r2 = null;
// This is the callback you try to define in your comment
Callback<Pair<? extends Entity, ? extends Entity>> cb = null;
// This is another option
Callback<Object> cb2 = null;
// Further option mentioned in comments
Callback<Pair<? extends Object, ? extends Object>> cb3 = null;
doubleRequestExecute(r1, r2, cb);
doubleRequestExecute(r1, r2, cb2);
doubleRequestExecute(r1, r2, cb3);
}
Pair<Integer, Integer> pII = new Pair<Integer, Integer>();
Pair<Object, Object> pOO = pII; // Compile error
pOO.setFirst("Whoa");
Integer i = pII.getFirst();
List<List<? super Integer>> l = null; // TODO
l.add(new ArrayList<Integer>());
l.add(new ArrayList<Number>());
l.add(new ArrayList<Objec>());
List<List<? super Integer>> l = new ArrayList<List<Integer>>(); // NO
List<List<? super Integer>> l = new ArrayList<List<Number>>(); // NOPE
List<List<? super Integer>> l = new ArrayList<List<Object>>(); // NEITHER
List<List<? super Integer>> l = new ArrayList<List<? super Integer>>(); // OK
// Only possible declaration
Callback<Pair<? super E1, ? super E2>> cb = new Callback<Pair<? super E1, ? super E2>>() {
...
}
doubleRequestExecute(new Request<E1>(), new Request<E2>(),
new Callback<Pair<? extends Object, ? extends Object>>() {
@Override public void onSuccess(Pair<? extends Object, ? extends Object> result) {}
@Override public void onFailure(Throwable caught) {}
});
public static < C extends Entity, D extends Entity, A extends C, B extends D > void doubleRequestExecute(
Request< A > request1, Request< B > request2,
Callback< Pair< C, D > > callback
) {
...
}
public static < A extends Entity, B extends Entity > void doubleRequestExecute(
Request< A > request1, Request< B > request2,
Callback< ? super Pair< A, B > > callback
) {
// change all Cs to As and Ds to Bs in the original code
}
doubleRequestExecute(
new Request<Entity>(), new Request<Entity>(),
new Callback< Pair< ?, ? > >() {
@Override public void onSuccess(Pair< ?, ? > result) {}
@Override public void onFailure(Throwable caught) {}
}
);
public static < C, D > void doubleRequestExecute(
Request< ? extends C > reqA, Request< ? extends D > reqB,
final Callback< Pair< C, D > > callback
) {
// change all As to Cs and Bs to Ds in the original code
}
doubleRequestExecute(
new Request<Entity>(), new Request<Entity>(),
new Callback< Pair< Object, Object > >() {
@Override public void onSuccess(Pair< Object, Object > result) {}
@Override public void onFailure(Throwable caught) {}
}
);
public static class PairCallback< A, B > implements Callback< Pair< A, B > > {
private final Callback< Pair< A, B > > cbDelegate;
public PairCallback( Callback< Pair< A, B > > cbDelegate ) {
this.cbDelegate = cbDelegate;
}
public void onSuccess( A a, B b ) {
onSuccess( new Pair< A, B >( a, b ) );
}
@Override public void onSuccess( Pair< A, B > p ) { cbDelegate.onSuccess( p ); }
@Override public void onFailure( Throwable caught ) { cbDelegate.onFailure( caught ); }
}
public static < A extends Entity, B extends Entity > void doubleRequestExecute(
Request< A > reqA, Request< B > reqB,
final PairCallback< ? super A, ? super B > callback
) {
final Holder< A > result1 = new Holder< A >();
final Holder< B > result2 = new Holder< B >();
reqA.execute(new Callback<A>() {
@Override public void onSuccess(A result) {
if (result2.value != null) {
callback.onSuccess(result, result2.value);
} else {
result1.value = result;
}
}
@Override public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
});
reqB.execute(new Callback<B>() {
@Override public void onSuccess(B result) {
if (result1.value != null) {
callback.onSuccess(result1.value, result);
} else {
result2.value = result;
}
}
@Override public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
});
}
private static class Entity1 extends Entity {}
private static class Entity2 extends Entity1 {}
public static void main( String... args ) {
doubleRequestExecute(
new Request< Entity >(), new Request< Entity >(),
new PairCallback< Object, Object >( new Callback< Pair< Object, Object > >() {
@Override public void onSuccess( Pair< Object, Object> result ) {}
@Override public void onFailure( Throwable caught ) {}
} )
);
doubleRequestExecute(
new Request< Entity2 >(), new Request< Entity1 >(),
new PairCallback< Entity1, Entity >( new Callback< Pair< Entity1, Entity > >() {
@Override public void onSuccess( Pair< Entity1, Entity > result ) {}
@Override public void onFailure( Throwable caught ) {}
} )
);
}