【问题标题】:What is the purpose of List<Void>?List<Void> 的目的是什么?
【发布时间】:2012-11-11 06:07:27
【问题描述】:

我什至不知道这是可行的,但是我在网上阅读一些代码时看到了一个带有这样签名的方法:

public List<Void> read( ... )

...什么?有没有理由这样做?这个List 还能有什么用?据我所知,无法实例化 Void 对象。

【问题讨论】:

标签: java list generics void


【解决方案1】:

List&lt;Void&gt; 很奇怪。它只能有null 元素,因为您不能创建Void 类型的对象。我认为这种东西没有实际用途。

Voidjava.lang 的一部分。这不是一个特殊的关键字或任何东西。它是一种“伪类型”(根据文档),用作占位符来表示对应于voidClass 对象,如Class&lt;Void&gt;。来自the docs for Class

Java 原始类型(booleanbytecharshortintlongfloatdouble)和关键字 void 也是表示为Class 对象。

Void 类的存在主要是为了这最后一部分,所以你可以这样写:

Class<Void> voidType = void.class; // == Void.TYPE

就像你可以写:

Class<Integer> intType = int.class; // == Integer.TYPE

【讨论】:

    【解决方案2】:

    这个方法签名可能是作为某个泛型类的副产品创建的。

    例如,SwingWorker 有两个类型参数,一个用于最终结果,一个用于中间结果。如果您只是不想使用任何中间结果,则将 Void 作为类型参数传递,导致某些方法返回 Void - 即什么都没有。

    如果SwingWorker 中有一个方法List&lt;V&gt; returnAllIntermediateResults()Void 作为类型参数V,它会创建一个方法,就像您在问题中发布的那样。

    代码将完全有效。您可以使用类型参数Void 实例化List 接口的任何实现(例如ArrayList)。但是Void 类型可以拥有的唯一值是null。因此,如果实现允许 null 元素,则列表只能包含 nulls 以外的任何其他内容。

    【讨论】:

    • 我明白了。很有意思!这很可能是我所看到的。谈论疯狂的产品。
    • 很好的答案,但您可以通过反射从技术上创建一个 Void 实例。我不知道你为什么要这样做。
    • @Jeff 我不太喜欢 Void 类型。通常当我看到它时,这意味着一些高级的难以理解的类型魔法正在发生。我看到的唯一“合理”用途是 SwingWorker。
    • Void 类型通常用于接受泛型类型的回调机制,其中一种是返回类型。如果函数或回调不返回任何内容,则可以是 Void。例如,Android 的AsyncTask 接受Result 的类型作为第三个通用参数。这理论上可以是任何东西,因为它无论如何都不会被使用,但Void 类型通常用于明确其目的。
    【解决方案3】:

    我同意,这很奇怪。

    如果您想扩展泛型类并从方法返回 void,我可以看到它的用途。我遇到了一个案例,我想使用int,但不得不使用Integer,因为java泛型不喜欢原始类型。

    public interface ObjectUserPool<E, T> {
        public E useObject(T o);
    }
    
    public class NonReturningObjectUserPool extends ObjectUserPool<Void, Integer> {
        public Void useObject(Integer i);
    }
    

    我认为这就是 java API 所说的,但老实说,我真的找不到 NonReturningObjectUserPool 的用途。

    【讨论】:

    • 您可以为任何引用类型返回null;它不需要像Void 这样的特殊内容。
    • @TedHopp 好点,答案已编辑。我认为想要返回 void 进行自我记录仍然是有效的;而不是声称返回 Integer 然后在内部总是返回 null,并在 javadoc 中声称你总是返回 null 或其他东西。
    【解决方案4】:

    它可能有用的一种情况是,如果您想从函数返回一组返回值。说

    static List<T> forEach(Func<A,T> func, List<A> items) {
       List<T> ret = new List<T>();
       for(int i = 0; i< items.length; i++) {
         ret.add(func.call(items[i]);
       }
       return ret;
    }
    
    public static void main() {
      ...
      List<Void> boringResult = 
       forEach(
        new Func<Void, Integer> {@override Void call(Integer i) {...}});
    }
    

    没那么有用,但您可以看到一个需要它的案例。

    【讨论】:

    • 嗯。谈论一个边缘案例。感谢您的回答!很有趣。
    • java.concurrent.FutureCallable 添加到列表中。有一个Void 返回类型并不少见。
    • Void call(Integer i) {...} 唯一可能的返回值是null,因为(根据the docs):“Void 类是一个不可实例化 占位符类"(强调)。我不确定构造一个只能包含null 引用的列表有多大用处。
    • @TedHopp - 同意,但如果您使用的是通用函数,例如上面的 forEach,则支持它可能更容易,然后禁止或创建另一个重载。
    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    相关资源
    最近更新 更多