重複の可能性:
Java Void 参照型の使用?
Void
現実世界の問題におけるクラスの実際の使用法は何ですか? このクラスはどのシナリオで使用できますか?
ExecutorService
オブジェクトを提供する必要があるオブジェクト ( など) がある場合Callable<T>
は、それを に渡してCallable<Void>
Callable が何も返さないことを示すことができます。Callable<T>
一部のタイプでパラメーター化する必要がVoid
あるため、タイプの欠如を示すために提供されています。
-他のラッパーVoid
クラスとは異なり、型の値をそれ自体に格納しないため、本質的にラッパーではありません。void
- javadocによるVoid
クラスが存在するのは、void キーワードをオブジェクトとして表す必要がある場合があるためです。
-しかし同時に、new 演算子を使用して Void クラスのインスタンスを作成することはできません。これは、Void のコンストラクターがprivate として宣言されているためです。さらに、Void クラスは final クラスであるため、このクラスを継承する方法はありません。
-したがって、Void
クラスの存在のために残っている唯一の目的は、メソッドの戻り値の型を void として取得できるリフレクションです。
Void
クラスは Java-reflection で使用されます。Method#getReturnType
を参照
Java リフレクション API は、Luke Woodward が指摘するように、void を返すメソッドの戻り値の型を表すために Void.TYPE を使用します。(私が以前考えていたように Void.class を返すと、java.lang.Void の戻り値の型を宣言して返すメソッドがあいまいになります)。
void test(){...};
Method handleForTest = ...;
assert(handleForTest.getReturnType() == Void.TYPE);
Post Java 1.5 Void をジェネリック クラスで使用して、それらが値を返さないことを示すことができます。実装は引き続き null を返す必要がありますが、それが Void 型の唯一の有効な値であるため、無視できます。
interface<T> Example{
//Implementations may do something and return a result
T doSomeThing();
}
class ExampleVoid implements Example<Void>{
//does something without returning a result
Void doSomething(){return null;}
}
また、Java では、メソッドを上書きするときに、より具体的な戻り値の型を指定できます。これは基本的に上記の一般的な例と同じですが、元の戻り値の型が Object の場合にジェネリックなしで機能することを示しています。(Void は他のすべての Java 型と同じ規則に従うため、オブジェクトに限定されます。残念ながら、これに無名の null 型を使用する方法はありません)
interface Example{
//Implementations may do something and return a result
Object doSomeThing();
}
class ExampleVoid implements Example{
//does something without returning a result
Void doSomething(){return null;}
}
JLS#14.8. Expression Statements
C や C++ とは異なり、Java プログラミング言語では、特定の形式の式のみを式ステートメントとして使用できます。Java プログラミング言語では「void へのキャスト」が許可されていないことに注意してください。void は型ではありません。
(void)... ; // incorrect!
動作しません。一方、Java プログラミング言語では、式ステートメントで最も有用な種類の式をすべて使用でき、void メソッドを呼び出すための式ステートメントとして使用されるメソッド呼び出しを必要としないため、このようなトリックはほとんど必要ありません。トリックが必要な場合は、代わりに代入ステートメント (§15.26) またはローカル変数宣言ステートメント (§14.4) を使用できます。
void.class (§8.4.5) の型は です
Class<Void>
。
メソッド宣言の結果は、メソッドが返す値の型 (戻り値の型) を宣言するか、キーワード void を使用してメソッドが値を返さないことを示します。
Void クラスは、Java キーワード void を表す Class オブジェクトへの参照を保持する、インスタンス化できないプレースホルダー クラスです。
メソッドの戻り値の型を確認したい場合のリフレクション目的で使用されます
if (getClass().getMethod("someMethod").getReturnType() == Void.TYPE)
同じことがジェネリック メソッドにも適用されます。
final Callable<Void> callable = new Callable<Void>() {
public Void call() {
return null;
}
};
このVoid
型は、外部システム (JNI、アプレットからの JavaScript 呼び出しなど) とのコールバックとインターフェースを可能にするために導入され、Java 1.1 の時代から、インターフェースの型が不明な場合に使用されてきました。または他のインターフェースによって強制されます(したがって、void
キーワードを使用できない場所)。Java は、プリミティブと null 参照を除いて、「すべてがオブジェクト」のような言語として設計されているため、期待される型が存在しないことを示すために、ダミーのラッパー/プレースホルダーが必要でした。
メソッドは、JLS ( §8.4.5 ) のメソッド戻り値の型セクションで定義されているように、戻り値の型で正式に宣言する必要があります。
メソッド宣言の結果は、メソッドが返す値の型 (戻り値の型) を宣言するか、キーワード
void
を使用してメソッドが値を返さないことを示します。
クラスリテラルのJLSセクションで述べたように(§15.8.2):
void.class
( §8.4.5 )の型はClass<Void>
Java 5 でのジェネリックの導入により、これらのインターフェイスの定義でジェネリックを使用できるようになり、これらのインターフェイスとコールバックの使用を型チェックできるようになるため、その使用法がより顕著になりました。AccessController
以前は、安全なコード パスを定義するためにアプレットで非常に頻繁に使用される を使用した特権実行ブロックの場合など、渡されたオブジェクトまたは戻りオブジェクトがないことを認識するのは実装者次第でした。
somemethod() {
// ...normal code here...
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
// privileged code goes here, for example:
System.loadLibrary("awt");
return null; // nothing to return
}
});
// ...normal code here...
}
この同じコードの Java 1.4 バージョンとの違いに注意してください。ここでは、何も返されないことが呼び出し元に明らかではありませんでした (そしてタイプ セーフでもありません)。
somemethod() {
// ...normal code here...
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
// privileged code goes here, for example:
System.loadLibrary("awt");
return null; // nothing to return
}
});
// ...normal code here...
}