【问题标题】:What's the difference between Void and no parameter?Void 和无参数有什么区别?
【发布时间】:2012-12-25 11:45:42
【问题描述】:

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

public void handle(Void e) 

protected void handle() 

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


这两者有什么区别?

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

【问题讨论】:

  • 根据参数和可以调用的访问权限,如果handle()调用第二个方法,handle(null)或者handle(null)调用第一个
  • @VinitPrajapati.. 你不能实例化Void
  • @RohitJain 更正评论
  • 我觉得不一样

标签: java void


【解决方案1】:

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

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

因为Void类不能被实例化,你可以传递给带有Void类型参数的方法的唯一值,例如handle(Void e),是null


那是事件的官方版本,但是对于那些感兴趣的人,尽管在 Void 的 javadoc 中声称相反,您可以实际实例化 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这样使用时,这是一个明确的信号,即返回值并不重要,即使使用@987654335 @ 接口是必需的,例如如果使用Executor 框架。

【讨论】:

  • 这并不意味着“不关心类型”它意味着“我什么都不想要返回,但泛型不支持void,因为它不是一个类,所以我改用Void "。
  • +1 我相信你可以通过反射实例化Void 的实例。
  • @Adam 这听起来像是一个奇怪的要求,但你会接受另一个答案吗?原因是如果我的一个答案超过了接受的答案,我会得到一顶特殊的“帽子”。这将是一个很好的圣诞礼物:) - 谢谢
  • @Adam 应该是 介意,而不是 Ming :) 那是 iPhone 的自动修正 crapnology 给你... :/
  • 我使用Void,也许是非常规地,在使用更多参数扩展方法时解决冲突(不要问为什么)。如果需要将methodA(String) 扩展为methodA(String, String),但methodA(String, String) 已经存在但具有不同的含义,我会将第一个方法扩展为methodA(String, Void, String)(并将其称为methodA(strA, (Void)null, strB))。当然,我可以做到methodB(String, String),但有时不行。 (同样,不要问为什么!)
【解决方案2】:

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

【讨论】:

  • 使用 Void 作为参数有什么目的吗?
  • 不,正如 Bohemian 所说,它的存在是为了能够表示 void 方法的返回值以进行反射。
  • 那么,使用函数的Void 参数的具体用例是什么?
【解决方案3】:

考虑从the Android systemAsyncTask&lt;T1, T2, T3&gt; 的API,它提供了三个钩子:

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

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

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

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

【讨论】:

  • Void ... 需要保留参数计数,因此onProgressUpdate 正确覆盖父级中的相同方法(因为在 java 中,不向 this 传递参数会导致它成为一个新函数,而不是而不是覆盖)。
【解决方案4】:

如果 Void 实际上不是类型参数的实例化(这显然是有意义的),那么如果您的 handle 方法受制于一个语言外契约,那么声明 handle(Void) 也是有意义的。想要参与某个协议的对象必须实现一个单参数句柄方法,而不管实际参数类型如何。现在,可能有一个特殊情况的实现除了null 之外什么都不能处理,所以为这样的实现声明handle(Void) 是有意义的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    • 2017-12-05
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多