Java generics void / пустые типы

#java #void #return-type

#java #пустота #возвращаемый тип

Вопрос:

Я реализую ResponseHandler для пакета apache HttpClient, вот так:

 new ResponseHandler<int>() {
    public int handleResponse(...) {
        // ... code ...
        return 0;
    }
}
  

но я бы хотел, чтобы handleResponse функция ничего не возвращала, т.е. void . Возможно ли это? Следующее не компилируется, поскольку void не является допустимым типом Java:

 new ResponseHandler<void>() {
        public void handleResponse(...) {
            // ... code ...
        }
}
  

Полагаю, я мог бы заменить void на Void , чтобы вернуть Void объект, но это не совсем то, что я хочу. Вопрос: возможно ли организовать эту ситуацию обратного вызова таким образом, чтобы я мог вернуться void из handleResponse ?

Ответ №1:

Void Тип был создан именно для этой ситуации: для создания метода с общим типом возвращаемого значения, где подтипом может быть «void». Void был разработан таким образом, что никакие объекты этого типа не могут быть созданы. Таким образом, метод типа Void всегда будет возвращать null (или завершаться ненормально), что настолько близко к нулю, насколько вы собираетесь получить. Вам действительно нужно поместить return null в метод, но это должно быть лишь незначительным неудобством.

Короче говоря: используйте Void .

Комментарии:

1. Arrgh — проблема дженериков проблема в том, что если, допустим, вы определяете возвращаемый тип «Void», вы должны ввести «return (null);» основная причина объявления возвращаемого типа void заключается в том, что вам не нужно иметь оператор return и вы можете использовать существующий метод «void» 🙂 Часть проблемы с Java Generics заключается в смешении проверки типов во время выполнения с необходимостью генерации кода во время компиляции и помощи в «бухгалтерском учете». Нужны «макросы» и «шаблоны», которые обеспечивают удобство при написании кода на стороне языка .

2. 1 Чтобы уточнить, Void существует со времен JDK1.1. Изначально он был создан для использования с Reflection, но играет аналогичную роль в generics.

3. @ILMTitan Не могли бы вы, пожалуйста, дать какие-либо ссылки на документацию о операторе «return null» в методах, которые определены для возврата Void?

4. @andriy-simonov Методы с возвращаемым типом void не обязательно возвращать значение. Методы с возвращаемым типом Object или любого подкласса, такие как Void , должны возвращать значение (или не завершаться нормально). Единственное значение, которое может быть присвоено Void и для этого возвращено из Void метода, является null .

Ответ №2:

Generics обрабатывает только классы объектов. типы void и primitive не поддерживаются Generics, и вы не можете использовать их в качестве параметризованного типа. Вместо этого вы должны использовать Void.

Можете ли вы сказать, почему вы не хотите использовать Void ?

Комментарии:

1. я бы просто предпочел не включать return оператор в функцию, где я ничего не возвращаю, в основном для чистоты.

2. Вы могли бы создать абстрактную оболочку, которая вызывает ваш void метод и возвращает null , чтобы скрыть это уродство.

3. 1 за напоминание мне, что «любая проблема в информатике может быть решена путем добавления уровня косвенности»

4. @TravisWebb Учитывая ваши конкретные потребности, просто вообще не используйте generics и возвращайте Object type, если это сработает

Ответ №3:

Когда вам нужно вернуть java.lang.Void , просто верните null .

Ответ №4:

У вас не может быть примитивов в generics, так что это int на самом деле Integer . Объект Void аналогичен ключевому слову void для generics.

Комментарии:

1. void это не примитив, это просто ключевое слово java. У него нет «типа»

2. и это, конечно же, не синонимы! void (нижний регистр) — ключевое слово, ничего не возвращено; Void (верхний регистр) — (не подлежащий удалению) класс , экземпляр этого возвращаемого класса (может быть только null с момента не подлежащего удалению)

3. @Carlos Heuberger аналогичный вариант вам больше подходит?

Ответ №5:

Это java.lang.Реализация Void в Java говорит сама за себя. Кроме того, я написал статью, которая связывает это с generics. Потребовалось немного подумать, прежде чем я начал понимать это: http://www.siteconsortium.com/h/D00006.php. ТИП уведомления = Class.getPrimitiveClass(«void»);

пакет java.lang;

 public final class Void {

    public static final Class<Void> TYPE = Class.getPrimitiveClass("void");

    private Void() {}
}
  

Ответ №6:

Увы, это невозможно. Вы можете настроить код на возврат Void , как вы говорите, однако вы никогда не сможете создать экземпляр a Void , поэтому вы не можете фактически написать функцию, которая соответствует этой спецификации.

Подумайте об этом так: общая функция говорит «эта функция возвращает что-то типа X», и вы можете указать X, но вы не можете изменить предложение на «эта функция ничего не возвращает». (Я не уверен, согласен ли я с этой семантикой, но так оно и есть.)

В этом случае, что я всегда делаю, это просто заставляю функцию возвращать тип Object и фактически всегда возвращаю null .

Комментарии:

1.Поскольку при типе возвращаемого объекта компилятор не может гарантировать, что возвращается только null. Расширяя ответ Томаса, попробуйте эти: static Void v() { return null; } static Void n() { return "NotAllowed"; } static Object o() { return "Allowed"; }

2. Да, я знаю, на данный момент это древняя история, но, поскольку я недавно оказался здесь, хотел заявить, что этот ответ на самом деле неверен. Вы можете возвращать тип Void. Это правда, что у вас не может быть созданного объекта этого типа, но поскольку все типы объектов в Java имеют значение null, вы можете вернуть null. По сути, то, что вы делаете с типом объекта, — это то, что вы должны делать с типом Void. Тип Void правильно выражает, что когда-либо будет возвращен только null.