web-dev-qa-db-ja.com

Voidとパラメーターなしの違いは何ですか?

私は2つのオーバーロードされたメソッドを定義するクラスを持っています

_public void handle(Void e) 

protected void handle() 
_

明らかに違います。特にhandle(Void e)publicです。


これら2つの違いは何ですか?

最初のメソッドを呼び出す方法は?私はhandle(null)を使用しています-これは正しいですか?

59
Adam Lee

最初の関数は、1つの引数の関数であり、指定する必要があり、有効な値はnullのみです。 null以外の値はコンパイルされません。 2番目の関数は引数を取らず、nullを渡してもコンパイルされません。

41
Confusion

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フレームワークを使用する場合。

65
Bohemian

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パラメーターを使用してこれらのメソッドを呼び出すことができます。

14
Raffaele

Voidが実際に型パラメーターのインスタンス化ではない場合(明らかに理にかなっている場合)、handleメソッドが対象である場合、handle(Void)を宣言することにも意味があります。特定のプロトコルに参加したいオブジェクトは、実際の引数のタイプに関係なく、1引数ハンドルメソッドを実装する必要があると言っている言語外契約に。現在、null以外は処理できない特殊なケースの実装が存在する場合があるため、そのような実装に対してhandle(Void)を宣言することは理にかなっています。

6
Marko Topolnik