2つのオーバーロードされたメソッドを定義するクラスがあります
public void handle(Void e)
protected void handle()
明らかにそれらは異なります、特にhandle(Void e)
ですpublic
。
これら2つの違いは何ですか?
最初のメソッドを呼び出す方法は?私が使用してhandle(null)
います-これは正しいですか?
Void
は通常リフレクションにのみ使用される特別なクラスです。その主な用途は、voidメソッドの戻り型を表すことです。のjavadocからVoid
:
Voidクラスは、Javaキーワードvoidを表すClassオブジェクトへの参照を保持するためのインスタンス化できないプレースホルダークラスです。
Void
クラスはインスタンス化できないため、Void
型パラメータ(、など)を使用してメソッドに渡すことができる値は。だけhandle(Void e)
ですnull
。
これはイベントの公式バージョンですが、興味のある人は、のjavadocで反対の主張があるにもかかわらず、実際に次のインスタンスをインスタンス化Void
できますVoid
。
Constructor<Void> c = Void.class.getDeclaredConstructor();
c.setAccessible(true);
Void v = c.newInstance(); // Hello sailor!
そうは言っVoid
ても、タイプが「無視」されていることを示したい場合、ジェネリックパラメータータイプとして「便利に」使用されるのを見てきました。たとえば、次のようになります。
Callable<Void> ignoreResult = new Callable<Void> () {
public Void call() throws Exception {
// do something
return null; // only possible value for a Void type
}
}
Callable
のジェネリックパラメータは戻り型であるため、このように使用すると、たとえばフレームワークを使用する場合などVoid
、インターフェイスの使用が必要な場合でも、戻り値は重要ではないことがコードの読者に明確に示されます。Callable
Executor
最初の関数は単一の引数の関数であり、これを指定する必要があり、値を有効に取ることができますnull
。null以外の値はコンパイルされません。2番目の関数は引数をとらず、それに渡すnull
とコンパイルされません。
3つのフックを提供するAndroidシステムAsyncTask<T1, T2, T3>
からのAPIについて考えてみます。
class AsyncTask<S, T, V> {
void doInBackground(S...);
void onProgressUpdate(T...);
void onPostExecute(V);
}
ジェネリック型を拡張すると、進行状況フックと結果AsyncTask<T1, T2, T3>
フックのパラメーターを使用することに興味がない場合があるため、実装は次のようになります。
class HTTPDownloader extends AsyncTask<URL, Void, Void> {
void doInBackground(URL... urls) {}
void onProgressUpdate(Void... unused) {}
void onPostExecute(Void unused) {}
}
インスタンス化できないnull
ため、パラメータを使用してこれらのメソッドを呼び出すことができます。Void
Void
が実際には型パラメーターのインスタンス化ではない場合(明らかに意味がある場合)、メソッドが特定のプロトコルに参加したいオブジェクトが実装する必要があるという言語外コントラクトの対象であるhandle(Void)
かどうかを宣言することにも意味があります実際の引数のタイプに関係なくhandle
、1つの引数のハンドルメソッド。さて、何も処理できない特殊なケースの実装があるかもしれませんが、そのような実装null
を宣言することは理にかなっていhandle(Void)
ます。