Void和没有参数有什么区别?

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

public void handle(Void e) protected void handle() 

显然他们是不同的,特别是handle(Void e)public

这两者有什么区别?

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

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

Void是一个通常只用于reflection的特殊类 – 它的主要用途是表示void方法的返回types。 从javadoc的Void

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

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

这是事件的正式版本,但对于那些有兴趣的人,尽pipe在Void的javadoc中有相反的声明,但实际上可以实例化一个Void的实例:

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

也就是说,当你想要指示types被“忽略”的时候,我已经看到了“有用”的Void作为generics参数types,例如:

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

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

考虑从Android系统到AsyncTask<T1, T2, T3>的API,它提供了三个钩子:

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

在扩展genericstypesAsyncTask<T1, T2, T3>您可能对使用进度结果钩子的参数不感兴趣,因此您的实现将如下所示:

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

你可以用null参数调用这些方法,因为Void不能实例化。

如果Void实际上不是一个types参数的实例(它显然是有意义的),那么在声明一个handle(Void)如果你的handle方法受到一个超语言合约的约束,这个合约说想要参与的对象在某个协议中必须实现一个参数的句柄方法 ,而不pipe实际的参数types。 现在,可能会有一个特殊情况的实现,它不能处理任何东西,只能是null所以为这样的实现声明handle(Void)是有意义的。