В чем разница между Void и no параметром?


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

public void handle(Void e) 

protected void handle() 

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


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

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

4 58

4 ответа:

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

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

Void класс является uninstantiable класс заполнитель для хранения ссылки на объект класса, представляющего в Java ключевое слово 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 основы.

рассмотрим 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 не может быть инстанцирован.

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