Void与无参数之间有什么区别?

时间:2012-12-25 11:45:43

标签: java void

我有一个定义了两个重载方法的类

public void handle(Void e) 

protected void handle() 

显然它们不同,尤其是handle(Void e)public


这两者有什么区别?

如何调用第一种方法?我正在使用handle(null) - 这是正确的吗?

4 个答案:

答案 0 :(得分:63)

Void是一个通常仅用于反射的特殊类 - 它的主要用途是表示void方法的返回类型。来自javadoc for Void

  

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

由于无法实例化Void类,因此您可以传递给具有Void类型参数的方法的唯一值(例如handle(Void e))为null


这是事件的正式版本,但对于那些感兴趣的人,尽管在Void的javadoc中声称相反,但可以实际实例化Void的实例:< / p>

Constructor<Void> c = Void.class.getDeclaredConstructor();
c.setAccessible(true);
Void v = c.newInstance(); // Hello sailor!


也就是说,当你想表明该类型被“忽略”时,我已经看到Void“有用”用作通用参数类型,例如:

Callable<Void> ignoreResult = new Callable<Void> () {
    public Void call() throws Exception {
        // do something
        return null; // only possible value for a Void type
    }
}

Callable的泛型参数是返回类型,所以当像这样使用Void时,对于代码的读者来说这是一个明确的信号,即返回值并不重要,即使使用需要Callable接口,例如,如果使用Executor框架。

答案 1 :(得分:40)

第一个函数是单个参数的函数,必须提供该参数,并且只能有效地取值null。除null之外的任何值都不会编译。第二个函数不接受任何参数,并且将null传递给它将无法编译。

答案 2 :(得分:14)

考虑来自the Android systemAsyncTask<T1, T2, T3>的API,它提供了三个钩子:

class AsyncTask<S, T, V> {
  void doInBackground(S...);
  void onProgressUpdate(T...);
  void onPostExecute(V);
}

当您扩展泛型类型AsyncTask<T1, T2, T3>时,您可能对使用 progress result 挂钩的参数不感兴趣,因此您的实现将如下所示:

class HTTPDownloader extends AsyncTask<URL, Void, Void> {
  void doInBackground(URL... urls) {}
  void onProgressUpdate(Void... unused) {}
  void onPostExecute(Void unused) {}
}

并且您可以使用null参数调用这些方法,因为Void无法实例化。

答案 3 :(得分:6)

如果Void实际上不是类型参数的实例化(显然有意义),那么如果handle(Void)方法受到handle方法的约束,则声明null一个extralinguistic契约,表示想要参与某个协议的对象必须实现一个参数句柄方法,而不管实际的参数类型。现在,可能有一个特殊情况的实现无法处理除handle(Void)以外的任何内容,因此为这样的实现声明{{1}}是有意义的。