私は2つのオーバーロードされたメソッドを定義するクラスを持っています
_public void handle(Void e)
protected void handle()
_
明らかに違います。特にhandle(Void e)
はpublic
です。
これら2つの違いは何ですか?
最初のメソッドを呼び出す方法は?私はhandle(null)
を使用しています-これは正しいですか?
最初の関数は、1つの引数の関数であり、指定する必要があり、有効な値はnull
のみです。 null以外の値はコンパイルされません。 2番目の関数は引数を取らず、null
を渡してもコンパイルされません。
Void
は、通常リフレクションのみに使用される特別なクラスです。その主な用途は、voidメソッドの戻り値の型を表すことです。 javadoc for Void
から:
Voidクラスは、Javaキーワードvoidを表すClassオブジェクトへの参照を保持するインスタンス化不可能なプレースホルダークラスです。
Void
クラスはインスタンス化できないため、handle(Void e)
などのVoid
型パラメーターを使用してメソッドに渡すことができる値は、null
のみです。
これはイベントの公式バージョンですが、興味のある人は、Void
のjavadocに反対の主張があるにもかかわらず、あなたはcan実際に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
フレームワークを使用する場合。
Android system からのAsyncTask<T1, T2, T3>
へのAPIを考えてください。これは3つのフックを提供します:
class AsyncTask<S, T, V> {
void doInBackground(S...);
void onProgressUpdate(T...);
void onPostExecute(V);
}
ジェネリック型AsyncTask<T1, T2, T3>
を拡張する場合、progressおよびresultフックにパラメーターを使用することに興味がないかもしれません。したがって、実装は次のようになります。
class HTTPDownloader extends AsyncTask<URL, Void, Void> {
void doInBackground(URL... urls) {}
void onProgressUpdate(Void... unused) {}
void onPostExecute(Void unused) {}
}
null
はインスタンス化できないため、Void
パラメーターを使用してこれらのメソッドを呼び出すことができます。
Void
が実際に型パラメーターのインスタンス化ではない場合(明らかに理にかなっている場合)、handle
メソッドが対象である場合、handle(Void)
を宣言することにも意味があります。特定のプロトコルに参加したいオブジェクトは、実際の引数のタイプに関係なく、1引数ハンドルメソッドを実装する必要があると言っている言語外契約に。現在、null
以外は処理できない特殊なケースの実装が存在する場合があるため、そのような実装に対してhandle(Void)
を宣言することは理にかなっています。