为什么JDK中存在Void包装类?

时间:2012-11-11 13:26:44

标签: java void

  

可能重复:
  Uses for the Java Void Reference Type?

Void类在现实问题中的真实用法是什么?在哪种情况下我们可以使用这个类?

6 个答案:

答案 0 :(得分:14)

如果您有一个要求提供ExecutorService对象的对象(如Callable<T>),则可以将Callable<Void>传递给它,以表明您的Callable不会返回任何内容。 Callable<T>必须在某种类型上进行参数化,因此提供Void表示缺少类型。

答案 1 :(得分:12)

- 与其他包装器Void不同,类存储类型void的值,因此不真正本质的包装

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

- 但同时我们不能使用new运算符创建Void类的实例。这是因为Void中的构造函数已经声明作为私人。 此外,Void类是一个final类,这意味着我们无法继承这个类。

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

答案 2 :(得分:7)

Void类用于Java反射 见Method#getReturnType

答案 3 :(得分:3)

java反射API使用Void.TYPE来表示返回void的方法的返回类型,如Luke Woodward所指出的那样。 (正如我之前认为的那样返回Void.class会导致返回声明java.lang.Void返回类型的方法的模糊性)。

 void test(){...};

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

Post java 1.5 Void可以在泛型类中用来表示它们不返回值 - Implementation仍然必须返回null,但是它可以被忽略,因为这是Void类型的唯一有效值。 p>

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

答案 4 :(得分:2)

JLS#14.8. Expression Statements

  

与C和C ++不同,Java编程语言只允许某些形式的表达式用作表达式语句。请注意,Java编程语言不允许“强制转换为无效” - 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;
        }
    };

答案 5 :(得分:2)

的原因

引入了Void类型以允许回调和与外部系统的接口(JNI,来自applet的JavaScript调用等等),并且自Java 1.1以来就一直存在这种情况接口类型未知或由其他接口强制执行的地方(因此您无法使用void keyword)。 Java已被设计 - 除了原语和空引用 - 作为“一切都是对象”的语言,需要一个虚拟的包装器/占位符来表示缺少预期的类型。

定义

由JLS的method return type部分定义的方法(§8.4.5),需要在返回类型中正式声明:

  

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

正如Class Literals§15.8.2)的JLS部分所述:

  

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

一般用途

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

  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 version of this same code的不同之处,即调用者不清楚(并且类型安全)没有返回任何内容:

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

进一步阅读和类似问题