Почему класс-оболочка Void существует в JDK? [Дубликат]

17

Каково реальное использование класса Void в реальных задачах? В каком сценарии мы можем использовать этот класс?

    
задан Community 11.11.2012 в 14:26
источник

6 ответов

14

Если у вас есть объект (например, ExecutorService ), который требует от вас предоставить объект Callable<T> , вы можете передать ему Callable<Void> , чтобы указать, что ваш Callable ничего не возвращает. Параметр Callable<T> должен быть параметризован для некоторого типа, поэтому указывается Void для указания отсутствия типа.

    
ответ дан mrb 11.11.2012 в 14:33
12

- В отличие от других оболочек Void class не хранит в себе значение типа void и, следовательно, не является оберткой в true сущность .

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

- Но в то же время мы не можем создать экземпляр класса Void с помощью оператора new. Это связано с тем, что конструктор в Void был объявлен как личное . Более того, класс Void является последним классом, что означает, что мы не можем наследовать этот класс.

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

    
ответ дан Kumar Vivek Mitra 11.11.2012 в 14:33
  • Практически не используется List <Void>. –  Amit Deshpande 11.11.2012 в 15:45
  • Но если вы хотите использовать непрактичное использование, List <Void> может использоваться как очень неэффективный счетчик :-) –  Stephen C 11.11.2012 в 16:12
  • Вы правы, хотя. Тип void (non) в Java не означает то же самое, что и void в C / C ++. Тип списка, в котором вам не нужен тип элемента, является List <?> ... not List <Void>. –  Stephen C 11.11.2012 в 16:19
  • Можно создать экземпляры класса Void с небольшим количеством рефлексивного хакера. –  Luke Woodward 11.11.2012 в 18:27
7
Класс

Void используется в Java-отражении.
смотрите метод # getReturnType

    
ответ дан Ilya 11.11.2012 в 14:30
3

API отражения java использует Void.TYPE для представления возвращаемого типа метода, возвращающего void, как указывает Люк Вудворд. (Возвращение Void.class, как я ранее думал, вызовет неоднозначность с методами, возвращающими объявление типа возврата java.lang.Void).

 void test(){...};

 Method handleForTest = ...;
 assert(handleForTest.getReturnType() == Void.TYPE);

Post Java 1.5 Void может использоваться в универсальных классах, чтобы указать, что они не возвращают значение - Реализация по-прежнему должна возвращать NULL, но его можно игнорировать, поскольку это единственное допустимое значение для типа Void.

interface<T> Example{
      //Implementations may do something and return a result
      T doSomeThing();
}

class ExampleVoid implements Example<Void>{
      //does something without returning a result
      Void doSomething(){return null;}
}

Кроме того, java позволяет задавать более конкретный тип возвращаемого значения при перезаписи метода, это в основном совпадает с приведенным выше общим примером, просто чтобы показать, что он работает без обобщенного типа, если исходный тип возвращаемого значения - Object. (он ограничен Object, поскольку Void следует тем же правилам, что и любой другой тип Java, к сожалению, для этого нет способа использовать безымянный нулевой тип)

interface Example{
      //Implementations may do something and return a result
      Object doSomeThing();
}

class ExampleVoid implements Example{
      //does something without returning a result
      Void doSomething(){return null;}
}
    
ответ дан josefx 11.11.2012 в 14:35
  • API отражения Java использует void.class как возвращаемый тип методов void, а не Void.class. В вашем первом примере утверждение не удастся. –  Luke Woodward 11.11.2012 в 18:25
  • @ LukeWoodward спасибо, я обновил свой ответ –  josefx 11.11.2012 в 19:24
2

JLS#14.8. Expression Statements

Unlike C and C++, the Java programming language allows only certain forms of expressions to be used as expression statements. Note that the Java programming language does not allow a "cast to void" - void is not a type - so the traditional C trick of writing an expression statement such as:

(void)... ;  // incorrect!

does not work. On the other hand, the Java programming language allows all the most useful kinds of expressions in expressions statements, and it does not require a method invocation used as an expression statement to invoke a void method, so such a trick is almost never needed. If a trick is needed, either an assignment statement (§15.26) or a local variable declaration statement (§14.4) can be used instead.

JLS#15.8.2. Class Literals

The type of void.class (§8.4.5) is Class<Void>.

JLS#8.4.5. Method Return Type

The result of a method declaration either declares the type of value that the method returns (the return type), or uses the keyword void to indicate that the method does not return a value.

Java doc Void

The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword void.

Он используется для целей отражения, когда вы хотите проверить тип возвращаемого значения метода

if (getClass().getMethod("someMethod").getReturnType() == Void.TYPE)

То же самое применимо к универсальным методам.

 final Callable<Void> callable = new Callable<Void>() {
        public Void call() {
             return null;
        }
    };
    
ответ дан Amit Deshpande 11.11.2012 в 14:53
2

Причины

Был введен тип Void , чтобы разрешить вызов -бэк и интерфейсы с внешними системами (JNI, вызовы JavaScript из апплетов и т. д.), и существует со времен Java 1.1 для таких случаев, когда тип интерфейса не известен или не применяется другим интерфейсом (и таким образом, где вы не можете использовать ключевое слово void ). Java была разработана - за исключением примитивов и нулевых ссылок - в качестве языка «все является объектом», для указания отсутствия ожидаемых типов требовалась фиктивная оболочка / заполнитель.

Определение

Метод, определенный возвращением метода тип раздела JLS ( §8.4 .5 ), нужно официально объявить при типе возврата:

The result of a method declaration either declares the type of value that the method returns (the return type), or uses the keyword void to indicate that the method does not return a value.

Как уже упоминалось в разделе JLS для литералов классов ( §15.8.2 ):

The type of void.class (§8.4.5) is Class<Void>

Общее использование

Его использование стало более заметным с введением обобщений в Java 5, так как он позволял определению этих интерфейсов использовать обобщенные элементы и позволял бы проверять использование этих интерфейсов и обратных вызовов. Раньше иногда до реализации требовалось знать, что не было ни переданного объекта, ни возвращаемого объекта, например, в случае привилегированного блока выполнения, использующего AccessController , очень часто используется в апплете для определения безопасных путей кода:

  somemethod() {
     // ...normal code here...
     AccessController.doPrivileged(new PrivilegedAction<Void>() {
         public Void run() {
             // privileged code goes here, for example:
             System.loadLibrary("awt");
             return null; // nothing to return
         }
     });
     // ...normal code here...
 }

Обратите внимание на разницу с Java версией 1.4 этого же кода / a>, где вызывающей стороне было неясно (и безопасно для типов), что ничего не возвращается:

   somemethod() {
        // ...normal code here...
        AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                // privileged code goes here, for example:
                System.loadLibrary("awt");
                return null; // nothing to return
            }
        });
       // ...normal code here...
  }

Дальнейшее чтение и подобные вопросы

ответ дан haylem 11.11.2012 в 20:15