简体   繁体   English

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

[英]What does <? super Void> mean?

I have encountered this class in code that I'm maintaining: 我在代码中遇到过这个类,我正在维护:

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

I'm having a really hard time understanding what this means. 我很难理解这意味着什么。 A Future containing a type that is either Void or its superclass - Object . 包含Void或其超类的类型的Future - Object So why not just write Future<Object> ? 那么为什么不写Future<Object>呢?

Something nobody else pointed out: it's Netty and if you look at https://netty.io/4.0/api/io/netty/util/concurrent/class-use/Future.html you'll see there are some methods taking just this type in the library, eg ChannelPromise.addListener(GenericFutureListener<? extends Future<? super java.lang.Void>> listener) . 没有其他人指出:它是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) And these methods have this signature because of the generic case: Future.addListener(GenericFutureListener<? extends Future<? super V>> listener) . 由于一般情况,这些方法具有此签名: Future.addListener(GenericFutureListener<? extends Future<? super V>> listener) ChannelPromise merely extends Future<Void> . ChannelPromise只是扩展了Future<Void>

The generic case makes sense because 1. if you have a FutureListener<Future<Object>> , it can handle any Object value when a future completes; 通用案例是有道理的,因为1.如果你有一个FutureListener<Future<Object>> ,它可以在未来完成时处理任何Object值; 2. since a V is an Object it can handle V . 2.由于V是一个Object它可以处理V Thus it can listen to a Future<V> . 因此它可以收听Future<V> Obviously the same holds for any supertype of V instead of Object . 对于任何超类型的V而不是Object显然也是如此。

Of course, these signatures would be much simpler if Java had declaration-site variance , but it doesn't and probably won't any time soon. 当然,如果Java具有声明站点差异 ,这些签名会更简单,但它不会,也可能不会很快。

It looks like this is being created to conform to some generic type like GenericFutureListener<Future<? super T>> 看起来这是为了符合GenericFutureListener<Future<? super T>>这样的通用类型GenericFutureListener<Future<? super T>> GenericFutureListener<Future<? super T>> , which is not flexible enough to allow for GenericFutureListener<Future<Void>> alone. GenericFutureListener<Future<? super T>> ,它不够灵活,不能单独使用GenericFutureListener<Future<Void>>

For instance if you have something like this: 例如,如果您有这样的事情:

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

Passing in just a GenericFutureListener<Future<Void>> is not allowed. 不允许GenericFutureListener<Future<Void>>

As you've noted, this Future<? super Void> 如你所知,这个Future<? super Void> Future<? super Void> can only be a void future, or Object future. Future<? super Void>只能是一个无效的未来,或者Object未来。

But: 但:

So why not just write Future? 那么为什么不写Future呢?

The intention of the developer was almost certainly to limit "listeners" to void actions. 开发人员的意图几乎肯定是限制“听众”无效行动。 But if one allowed Future<Object> , then any other type could be used as the Future 's value, because a Future<Object> could hold a String (or any other type) result. 但是如果允许Future<Object> ,那么任何其他类型都可以用作Future的值,因为Future<Object>可以保存String (或任何其他类型)结果。

java.lang.Void being a final class, it doesn't allow any child classes, which effectively almost completely limits it to void actions (unless one has practical value in calling new Object() when setting the result of the future) java.lang.Void是一个final类,它不允许任何子类,它实际上几乎完全将它限制为void操作(除非在设置未来结果时调用new Object()具有实际价值)

Yes, you can use a Future<Object> with that Listener, but the declaration makes it clear that the Listener should/does not use the result. 是的,您可以将Future<Object>与该Listener一起使用,但该声明清楚地表明Listener应该/不使用该结果。

Declaring this as GenericFutureListener<Future<Object>> gives the impression the Listener does something with the result. 将此声明为GenericFutureListener<Future<Object>>给出了Listener对结果执行某些操作的印象。

Sometimes we only care about the task has done or not. 有时我们只关心任务是否完成。

Someone (like me) may prefer to return Future<Void> to indicate that the task has no result. 有人(像我一样)可能更喜欢返回Future<Void>来表示任务没有结果。

While someone else may prefer to use Future<Object> or Future<?> and use null as the result. 而其他人可能更喜欢使用Future<Object>Future<?>并使用null作为结果。

I think this guy encountered both Future<Void> and Future<Object> . 我认为这个人遇到了Future<Void>Future<Object> So he use Future<? super Void> 所以他使用Future<? super Void> Future<? super Void> to adapt both generic. Future<? super Void>适应两种通用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM