18

可能重复:
Java Void 引用类型的用途?

Void类在现实世界问题中的真正用途是什么?我们可以在什么场景下使用这个类?

4

6 回答 6

15

ExecutorService如果您有一个需要您提供对象的对象(如 an ) Callable<T>,您可以传递它 aCallable<Void>以指示您的 Callable 不返回任何内容。Callable<T>必须在某些类型上进行参数化,因此Void提供以指示缺少类型。

于 2012-11-11T13:33:07.087 回答
13

-与其他包装器Void类不同,它本身不存储类型值,void因此本质上不是包装器

-Void根据javadoc的类之所以存在,是因为有时我们可能需要将 void 关键字表示为一个对象。

-但与此同时,我们不能使用 new 运算符创建 Void 类的实例。这是因为 Void 中的构造函数已被声明为私有。此外,Void 类是最终类,这意味着我们无法继承该类。

-Void所以类存在的唯一目的是反射,我们可以在其中获得方法的返回类型为 void。

于 2012-11-11T13:33:28.343 回答
7

Void类用于Java反射。
方法#getReturnType

于 2012-11-11T13:30:08.837 回答
3

正如 Luke Woodward 所指出的,java 反射 API 使用 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 类型相同的规则,遗憾的是没有办法为此使用无名 null 类型)

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;}
}
于 2012-11-11T13:35:40.990 回答
2

原因

引入该Void类型是为了允许与外部系统(JNI、来自小程序的 JavaScript 调用等)进行回调和接口,并且自 Java 1.1 以来一直存在,用于接口类型未知的情况或由其他接口强制执行(因此您不能使用void关键字)。Java 已经被设计为——除了原语和空引用——作为一种“一切都是对象”的语言,需要一个虚拟包装器/占位符来指示预期类型的​​缺失。

定义

由JLS(第8.4.5节)的方法返回类型部分定义的方法需要在返回类型处正式声明:

方法声明的结果要么声明方法返回的值的类型(返回类型),要么使用关键字void表示方法不返回值。

如 JLS 部分中提到的类文字§15.8.2):

void.class§8.4.5)的类型是Class<Void>

一般使用

随着 Java 5 中泛型的引入,它的使用变得更加突出,因为它允许这些接口的定义使用泛型,并允许对这些接口和回调的使用进行类型检查。以前,有时需要由实现者知道没有传递对象或没有返回对象,例如,在使用 的特权执行块的情况下,AccessControllerApplet 中经常使用它来定义安全代码路径:

  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 版本的区别,调用者不清楚(并且类型安全)没有返回任何内容:

   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...
  }

进一步阅读和类似问题

于 2012-11-11T19:15:47.690 回答
2

JLS#14.8. Expression Statements

与 C 和 C++ 不同,Java 编程语言只允许将某些形式的表达式用作表达式语句。请注意,Java 编程语言不允许“强制转换为 void”—— void 不是一种类型——因此编写表达式语句的传统 C 技巧,例如:

(void)... ;  // incorrect!

不起作用。另一方面,Java 编程语言允许在表达式语句中使用所有最有用的表达式,并且不需要将方法调用用作表达式语句来调用 void 方法,因此几乎不需要这样的技巧。如果需要技巧,可以使用赋值语句(第 15.26 节)或局部变量声明语句(第 14.4 节)来代替。

JLS#15.8.2. Class Literals

void.class (§8.4.5) 的类型是Class<Void>.

JLS#8.4.5. Method Return Type

方法声明的结果要么声明方法返回的值的类型(返回类型),要么使用关键字 void 表示方法不返回值。

Java doc Void

Void 类是一个不可实例化的占位符类,用于保存对表示 Java 关键字 void 的 Class 对象的引用。

当您想要检查方法的返回类型时,它用于反射目的

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

同样适用于通用方法。

 final Callable<Void> callable = new Callable<Void>() {
        public Void call() {
             return null;
        }
    };
于 2012-11-11T13:53:51.777 回答