Используется для Java Void Reference Type? - PullRequest
151 голосов
/ 13 марта 2009

Существует Java Void - прописные буквы V-- ссылочный тип . Единственная ситуация, которую я когда-либо видел, это параметризация Callable s

final Callable<Void> callable = new Callable<Void>() {
            public Void call() {
                foobar();
                return null;
            }
        };

Существуют ли другие варианты использования ссылочного типа Java Void? Можно ли когда-нибудь назначить что-либо кроме null? Если да, у вас есть примеры?

Ответы [ 11 ]

109 голосов
/ 13 марта 2009

Void стало соглашением для универсального аргумента, который вас не интересует. Нет никаких причин, по которым вы должны использовать любой другой неинстанцируемый тип, такой как System.

Он также часто используется, например, в Map значениях (хотя Collections.newSetFromMap использует Boolean, поскольку карты не должны принимать null значений) и java.security.PrivilegedAction.

Я написал запись в блоге на Void несколько лет назад.

47 голосов
/ 14 марта 2009

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

Constructor<Void> constructor = Void.class.getDeclaredConstructor();
constructor.setAccessible(true);
Void v = constructor.newInstance();
System.out.println("I have a " + v);

печатает что-то вроде

I have a java.lang.Void@75636731
27 голосов
/ 13 марта 2009

Future<Void> работает как шарм. :)

19 голосов
/ 13 марта 2009

Учитывая, что нет открытых конструкторов , я бы сказал, что ему нельзя назначить ничего, кроме null. Я использовал его только как заполнитель для «мне не нужно использовать этот универсальный параметр», как показывает ваш пример.

Он также может быть использован в отражении, из того, что его Javadoc говорит:

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

16 голосов
/ 14 марта 2009

Все классы примитивных оболочек (Integer, Byte, Boolean, Double и т. Д.) Содержат ссылку на соответствующий класс примитивов в статическом поле TYPE, например:

Integer.TYPE == int.class
Byte.TYPE == byte.class
Boolean.TYPE == boolean.class
Double.TYPE == double.class

Void изначально был создан как где-то, чтобы поместить ссылку на тип void:

Void.TYPE == void.class

Однако вы ничего не получите, используя Void.TYPE. Когда вы используете void.class, гораздо понятнее, что вы делаете что-то с типом void.

Кроме того, в последний раз, когда я пытался это сделать, BeanShell не распознал void.class, поэтому вы должны использовать Void.TYPE там.

6 голосов
/ 12 декабря 2013

Когда вы используете шаблон посетителя , может быть удобнее использовать Void вместо Object, если вы хотите быть уверены, что возвращаемое значение будет нулевым

Пример

public interface LeavesVisitor<OUT>
{
   OUT visit(Leaf1 leaf);

   OUT visit(Leaf2 leaf);
}

Когда вы реализуете своего посетителя, вы можете явно установить для OUT значение Void, чтобы вы знали, что ваш посетитель будет всегда возвращать ноль вместо использования Object

public class MyVoidVisitor implements LeavesVisitor<Void>
{
    Void visit(Leaf1 leaf){
        //...do what you want on your leaf
        return null;
    }

    Void visit(Leaf2 leaf){
        //...do what you want on your leaf
        return null;
    }
}
5 голосов
/ 15 марта 2009

До обобщения это было создано для API отражения, чтобы хранить TYPE, возвращаемый Method.getReturnType () для метода void, соответствующего другим классам примитивных типов.

РЕДАКТИРОВАТЬ: Из JavaDoc Void: «Класс Void является нереализуемым классом-заполнителем для хранения ссылки на объект Class, представляющий ключевое слово Java void». До Generics я не знаю ничего, кроме размышлений.

2 голосов
/ 07 января 2015

Поскольку вы не можете создать экземпляр Void, вы можете использовать Apache commons Пустой объект , поэтому

Null aNullObject = ObjectUtils.Null;
Null noObjectHere = null;

в первой строке у вас есть объект, поэтому aNullObject != null сохраняется, тогда как во второй строке нет ссылки, поэтому noObjectHere == null содержит

Чтобы ответить на первоначальный вопрос автора, для этого нужно различать «ничто» и «ничто», которые являются совершенно разными вещами.

PS: скажите нет объектному образцу Null

1 голос
/ 21 апреля 2012

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

public void onNewRegistration() {
    newRegistrationService.createNewUser(view.getUsername(), view.getPassword(),
            view.getInitialAmount(), view.getCurrency(), new AsyncCallback<Void>() {
      @Override
      public void onFailure(Throwable caught) {

      }

      @Override
      public void onSuccess(Void result) {
        eventBus.fireEvent(new NewRegistrationSuccessEvent());
      }
    });
  } 

здесь, как вы можете видеть, я не хочу ничего от сервера, который я запрашиваю для создания новых регистраций, но public interface AsyncCallback<T> { .... } является универсальным интерфейсом, поэтому я предоставляю Void, поскольку универсальные шаблоны не принимают примитивные типы

0 голосов
/ 13 декабря 2015

Это может быть редкий случай, но однажды я использовал Void в классах аспектов.

Это был аспект, который запускается после методов с аннотацией @Log и регистрирует возвращенный метод и некоторую информацию, если тип возвращаемого метода не void.

 @AfterReturning(value = "@annotation(log)", 
       returning = "returnValue", 
       argNames = "joinPoint, log, returnValue"
      )
    public void afterReturning(final JoinPoint joinPoint, final Log log,
            final Object returnValue) {

            Class<?> returnType = ((MethodSignature) joinPoint.getSignature())
            .getReturnType();
           if (Void.class.isAssignableFrom (returnType)) ) {
            //Do some log
         }
}
...