9

JavaジェネリックのVoid型のオブジェクトと無制限のワイルドカード型のオブジェクトの違いは何ですか? <?> の使用と、リフレクションの観点からの Void の使用も理解していますが、Java のソース コードを見て少し興味をそそられました。

java.util.concurrent.AbstractExecutorService

とその方法

public Future<?> submit(Runnable task) {
    ...
    RunnableFuture<Void> ftask = new TaskFor(task, null);
    ...
    return ftask;

メソッド内で RunnableFuture<?> の代わりに RunnableFuture<Void> を使用する場所

誰かがこの背後にある理由を理解するのを手伝ってもらえますか? ありがとう

4

3 に答える 3

16

Voidは、戻り値がないことを表すために使用される特別なクラスです。Void それ自体について特別なことは何もありませんが、インスタンス化することはできません (決してインスタンス化することはできません)。そのため、可能な唯一の値は alwaysnullです。次の 2 つの目的で使用されます。

  1. ジェネリック メソッドまたはクラスには戻り値がないと言うこと。
  2. voidを使用して Java リフレクションで戻り値の型を表すには、Void.TYPE. たとえば、メソッドが「void」を返すかどうかをリフレクションによって判断する方法を参照してください。

したがって、実際のクラスではなく、コンパイル時に特定の不明な型を表すワイルドカードとは大きく異なります。実行時に、他のすべてのジェネリック型と同様に消去されます。


方法についてsubmit。JDK 6 の 2 つの実装を次に示します。

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Object> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}

およびJDK 7:

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}

ご覧のとおり、タイプはVoidJDK 7 でのみに変更されました。これはおそらく、概念的により理にかなっているためです。ただし、メソッドのインターフェースを変更できなかったため (互換性の理由と、メソッドが ExecutorService インターフェースを実装Future<?> submit(Runnable task)しているため)、戻り値の型Future<?>は同じままでした。それが私の説明です。

于 2012-10-18T19:26:17.383 に答える
4

Void はワイルドカードではなく、返す値がまったくないことを表します。

ボイドjavadoc ...

于 2012-10-18T19:22:41.237 に答える
3

Voidは、voidのオブジェクト表現です。voidがメソッドから何も返さない場合、Voidは常にnullを返します。これは、voidがオブジェクトではないため、Genericsでは使用できないためです。戻り値が必要ない場合は、VoidwithFuturesを使用すると便利です。

于 2012-10-18T19:48:37.693 に答える