Подтвердить что ты не робот

Какая разница между параметрами Void и no?

У меня есть класс, который определяет два перегруженных метода

public void handle(Void e) 

protected void handle() 

Очевидно, что они разные, особенно handle(Void e) есть public.


Какая разница между этими двумя?

Как вызвать первый метод? Я использую handle(null) - это правильно?

4b9b3361

Ответ 1

Первая функция - это функция одного аргумента, которая должна быть предоставлена ​​и может действительным образом принимать значение null. Любое значение, отличное от нуля, не будет компилироваться. Вторая функция не принимает никакого аргумента и передает null, чтобы она не компилировалась.

Ответ 2

Void - это особый класс, обычно используемый только для отражения - его основное использование - представлять возвращаемый тип метода void. Из javadoc для Void:

Класс Void является неинтересным классом-заполнителем для ссылки на объект класса, представляющий ключевое слово void.

Поскольку класс 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.

Ответ 3

Рассмотрим API для AsyncTask<T1, T2, T3> из системы Android, которая предоставляет три крючка:

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 не может быть создан.

Ответ 4

Если Void на самом деле не является экземпляром параметра типа (где это, очевидно, имеет смысл), есть смысл в объявлении a handle(Void), если ваш метод handle подчиняется экстралингвистическому контракту, в котором говорится, что объект, который хочет участвовать в определенном протоколе, должен реализовать метод one-argument handle, независимо от фактического типа аргумента. Теперь может быть реализация специального случая, которая не может обрабатывать ничего, кроме null, поэтому имеет смысл объявить handle(Void) для такой реализации.