<!-是什么?超级虚空->是什么意思?

时间:2018-07-10 07:14:23

标签: java generics

我在维护的代码中遇到了此类:

new GenericFutureListener<Future<? super Void>>() {...}

我很难理解这意味着什么。包含类型为Future或其超类-Void的{​​{1}}。那么,为什么不只写Object呢?

5 个答案:

答案 0 :(得分:13)

没有其他人指出:这是Netty,如果您查看https://netty.io/4.0/api/io/netty/util/concurrent/class-use/Future.html,则会在库中看到一些采用这种类型的方法,例如ChannelPromise.addListener(GenericFutureListener<? extends Future<? super java.lang.Void>> listener)。由于一般情况,这些方法具有此签名:Future.addListener(GenericFutureListener<? extends Future<? super V>> listener)ChannelPromise仅扩展了Future<Void>

这种通用情况是有道理的,因为1.如果您有一个FutureListener<Future<Object>>,则在将来完成时它可以处理任何Object值; 2.由于VObject,因此可以处理V。因此,它可以收听Future<V>。显然,对于V而不是Object的任何超类型也是如此。

当然,如果Java具有declaration-site variance,这些签名会简单得多,但是现在没有,并且可能很快也不会。

答案 1 :(得分:9)

似乎是为了符合GenericFutureListener<Future<? super T>>之类的通用类型而创建的,该类型不够灵活,无法单独容纳GenericFutureListener<Future<Void>>

例如,如果您有类似这样的内容:

class GenericFutureListener<T> {}

public static <T> void m(GenericFutureListener<Future<? super T>> p) {
    ...
}
m(new GenericFutureListener<Future<? super Void>>() {}); // works,
m(new GenericFutureListener<Future<Void>>() {}); // does not work

不允许仅传入GenericFutureListener<Future<Void>>

答案 2 :(得分:2)

您已经注意到,Future<? super Void>只能是虚无的未来,也可以是Object的未来。

但是:

  

那为什么不只写《未来》呢?

几乎可以肯定,开发人员的意图是将“听众”限制为无效行为。但是,如果允许一个Future<Object>,那么任何其他类型都可以用作Future的值,因为Future<Object>可以容纳String(或任何其他类型)的结果

java.lang.Voidfinal类,它不允许任何子类,这实际上几乎将其完全限制为无效操作(除非在设置时调用new Object()具有实用价值)未来的结果)

答案 3 :(得分:0)

是的,您可以将Future<Object>与该侦听器一起使用,但是声明明确指出侦听器应该/不使用结果。

将其声明为GenericFutureListener<Future<Object>>给人的印象是听众对结果做了一些事情。

答案 4 :(得分:0)

有时我们只关心任务是否完成。

像我这样的人可能更愿意返回Future<Void>来表明任务没有结果。

虽然其他人可能更喜欢使用Future<Object>Future<?>并使用null作为结果。

我认为这个人同时遇到了Future<Void>Future<Object>。因此,他使用Future<? super Void>来适应这两种通用方法。