39

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

public List<Void> read( ... )

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

4

4 回答 4

26

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

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

如果有一个方法List<V> returnAllIntermediateResults()作为类型参数SwingWorker,它会创建一个方法,就像你在你的问题中发布的那样。VoidV

该代码将完全有效。您可以使用类型参数实例化List接口的任何实现(例如) 。但是一个类型可以拥有的唯一值是. 因此,如果实现允许元素,则列表只能包含s。ArrayListVoidVoidnullnullnull

于 2012-11-22T20:28:27.027 回答
12

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

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) {...}});
}

没那么有用,但您可以看到需要它的情况。

于 2012-11-22T20:38:00.420 回答
9

List<Void>很奇怪。它只能有null元素,因为您不能创建 type 的对象Void。我认为这样的事情没有实际用途。

Void是的一部分java.lang。这不是一个特殊的关键字或任何东西。它是一种“伪类型”(根据文档),用作占位符来表示Class对应于 的对象void,如Class<Void>. 从文档中Class

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

该类的Void存在主要是为了最后一部分,因此您可以编写:

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

就像你可以写:

Class<Integer> intType = int.class; // == Integer.TYPE
于 2012-11-22T20:27:10.417 回答
4

我同意,这很奇怪。

如果您想扩展泛型类并从方法返回 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.

于 2012-11-22T20:32:18.790 回答