我有一个定义两个重载方法的类
public void handle(Void e)
protected void handle()
显然它们是不同的,尤其handle(Void e)
是public
。
这两者有什么区别?
如何调用第一种方法?我正在使用handle(null)
- 这是正确的吗?
Void
是一个通常仅用于反射的特殊类 - 它的主要用途是表示 void 方法的返回类型。从javadoc 为Void
:
Void 类是一个不可实例化的占位符类,用于保存对表示 Java 关键字 void 的 Class 对象的引用。
因为Void
无法实例化该类,所以您可以传递给具有Void
类型参数的方法的唯一值,例如handle(Void e)
,是null
。
那是事件的官方版本,但是对于那些感兴趣的人,尽管在 的 javadoc 中声称相反Void
,您实际上可以实例化 的实例Void
:
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
框架。
第一个函数是单个参数的函数,必须提供并且只能有效地取值null
。null 以外的任何值都不会编译。第二个函数不接受任何参数并且传递null
给它不会编译。
考虑AsyncTask<T1, T2, T3>
来自Android 系统的 API ,它提供了三个钩子:
class AsyncTask<S, T, V> {
void doInBackground(S...);
void onProgressUpdate(T...);
void onPostExecute(V);
}
当您扩展泛型类型时AsyncTask<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
实际上不是类型参数的实例化(这显然是有意义的),那么声明一个handle(Void)
如果您的handle
方法受制于语言外契约的意义也很有意义,该契约说想要参与某个协议的对象必须实现单参数句柄方法,无论实际参数类型如何。现在,可能有一个特殊情况的实现不能处理任何事情,但是为这样的实现null
声明是有意义handle(Void)
的。