[英]What is the difference between java.lang.Void and void?
In API在 API
"The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword void." “Void 类是一个不可实例化的占位符类,用于保存对表示 Java 关键字 void 的 Class 对象的引用。”
java.lang.Void
be used?什么时候使用java.lang.Void
? If the class is "uninstantiable", what use is it?如果类是“不可实例化的”,它有什么用?java.lang.Void
and void
? java.lang.Void
和void
有什么区别?java.lang.Void
is analogous to java.lang.Integer
. java.lang.Void
类似于java.lang.Integer
。 Integer
is a way of boxing values of the primitive type int
. Integer
是一种将原始类型int
的值装箱的方式。 Void
is a way of boxing values of the primitive type void
. Void
是一种对原始类型void
的值进行装箱的方法。
"But wait, void
doesn't have any possible values!" “但是等等, void
没有任何可能的值!”
Right!正确的! That's what makes java.lang.Void
"uninstantiable".这就是使java.lang.Void
“不可实例化”的原因。 :) :)
It's a nice feature of the Java type system that every primitive type has a boxed equivalent. Java 类型系统的一个很好的特性是每个原始类型都有一个盒装的等价物。 int
has Integer
, long
has Long
, byte
has Byte
... and void
has Void
. int
有Integer
, long
有Long
, byte
有Byte
... 并且void
有Void
。 It would be weird and asymmetrical if Void
didn't exist.如果Void
不存在,那将是奇怪和不对称的。
"So what's the difference between java.lang.Void
and void
?" “那么java.lang.Void
和void
有什么区别?”
Easy.简单的。 void
is a primitive type. void
是原始类型。 Void
is an reference type that inherits from Object
. Void
是继承自Object
的引用类型。 They're similar in that neither of them has any possible values;它们的相似之处在于它们都没有任何可能的值。 but nevertheless they are two very different types, from the type system's point of view.但是,从类型系统的角度来看,它们是两种截然不同的类型。
"But I don't have any use for Void
in my programs." “但我的程序中对Void
没有任何用处。”
And I don't have any use for GarbageCollectorMXBean
in mine.而且我对GarbageCollectorMXBean
没有任何用处。 Some features don't have non-obscure uses.有些功能没有非晦涩的用途。 That's okay.没关系。
The most common use of Void
is for reflection, but that is not the only place where it may be used. Void
最常见的用途是反射,但这并不是唯一可以使用它的地方。
void
is a keyword that means that a function does not result a value. void
是一个关键字,表示函数不会产生值。
java.lang.Void
is a reference type, then the following is valid: java.lang.Void
是一个引用类型,那么以下是有效的:
Void nil = null;
(So far it is not interesting...) (到目前为止,它并不有趣......)
As a result type (a function with a return value of type Void
) it means that the function *always * return null
(it cannot return anything other than null
, because Void
has no instances).作为结果类型(返回值类型为Void
的函数),它意味着函数 *always * 返回null
(它不能返回null
以外的任何内容,因为Void
没有实例)。
Void function(int a, int b) {
//do something
return null;
}
Why would I like a function that always returns null?为什么我想要一个总是返回 null 的函数?
Before the invention of generics, I didn't have a use case for Void
.在泛型发明之前,我没有Void
的用例。
With generics, there are some interesting cases.对于泛型,有一些有趣的案例。 For instance, a Future<T>
is a holder for the result of an asynchronous operation performed by another thread.例如, Future<T>
是另一个线程执行的异步操作结果的持有者。 Future.get
will return the operation value (of type T
), and will block until the computation is performed. Future.get
将返回操作值(类型为T
),并将阻塞直到执行计算。
But... What if there is nothing to return?但是......如果没有什么可以返回怎么办? Simple: use a Future<Void>
.很简单:使用Future<Void>
。 For instance, in Google App Engine the Asyncronous Datastore Service delete
operation returns a future . When
例如,在 Google App Engine 中,异步数据存储服务delete
操作返回一个 future . When
. When
get() is invoked on that future,
null` is returned after the deletion is complete. . When
is invoked on that future,
get() 时,删除完成后返回 null`。 One could write a similar example with Callable s.可以用Callable写一个类似的例子。
Another use case is a Map
without values, ie a Map<T,Void>
.另一个用例是没有值的Map
,即Map<T,Void>
。 Such a map behaves like a Set<T>
, then it may be useful when there is no equivalent implementation of Set
(for instance, there is no WeakHashSet
, then one could use a WeakHashMap<T,Void>
).这样的映射的行为类似于Set<T>
,那么当没有Set
的等效实现时它可能很有用(例如,没有WeakHashSet
,那么可以使用WeakHashMap<T,Void>
)。
The only point of Void
is to hold Void.TYPE
, which is sort of like void.class
. Void
唯一的一点是持有Void.TYPE
,它有点像void.class
。 If you have a reflective reference to a method that returns void
, and you get its return type, it'll return Void.TYPE
.如果您对返回void
的方法有反射引用,并且您获得了它的返回类型,那么它将返回Void.TYPE
。
You cannot, and should not, use it for anything else.您不能也不应该将其用于其他任何事情。
Void is a AutoBoxing feature (since JDK 1.5) of void. Void 是 void 的一个自动装箱功能(从 JDK 1.5 开始)。
well its self explanatory that Void is reference whereas void is a primitive type.好吧,它的自我解释是 Void 是引用,而 void 是原始类型。
So, where the requirement comes to have to use Void ???那么,哪里有要求必须使用 Void ???
One common usage with Generic types where we can't use primitive.泛型类型的一种常见用法,我们不能使用原始类型。
Say, in case of Android
AsyncTaks<Params, Progress, Result>
what if I don't want to get Progress update.比如说,在 AndroidAsyncTaks<Params, Progress, Result>
的情况下,如果我不想获得 Progress 更新怎么办。 I can't use void (primitive type) here we require java.lang.Void我不能在这里使用 void (原始类型) 我们需要 java.lang.Void
Another example for using Void
is SwingWorker
另一个使用Void
的例子是SwingWorker
new SwingWorker<Void, Integer> () {
@Override
protected Void doInBackground(){
...
}
@Override
protected void process(List<Integer> chunk){
...
}
@Override
public void done(){
...
}
}.execute();
Void is useful because sometimes you need to specify the return type of a method outside the method itself. Void 很有用,因为有时您需要在方法本身之外指定方法的返回类型。
For example take this java 8 lambda expression , which checks whether an EventResource object has certain properties, using a method called checkBenefitConcertInCentralPark
, passed into the method checkCreatedEvent
:例如这个java 8 lambda 表达式,它使用一个名为checkBenefitConcertInCentralPark
的方法检查 EventResource 对象是否具有某些属性,并传递给方法checkCreatedEvent
:
eventChecker.checkCreatedEvent(TestEvents::checkBenefitConcertInCentralPark);
The checkBenefitConcertInCentralPark
method is defined like this (note the use of Void): checkBenefitConcertInCentralPark
方法是这样定义的(注意 Void 的使用):
public static Void checkBenefitConcertInCentralPark(EventResource eventResource) {
// JUnit code here...
// assertThat(blablabla :) )
return null; // we can only return null at the end of a method when returning Void
}
and then the checkBenefitConcertInCentralPark
method is passed into the method checkCreatedEvent
.然后将checkBenefitConcertInCentralPark
方法传递到方法checkCreatedEvent
中。
// Function<EventResource, Void> describes the checkBenefitConcertInCentralPark method
public void checkCreatedEvent(Function<EventResource, Void> function) {
function.apply(this.eventResource);
}
I've personally used it like this:我个人是这样使用它的:
@FunctionalInterface
interface MyPackagePrivateInterface<T, Next> {
//Returns next
Next compareAndSwap(T prev);
}
@FunctionalInterface
public interface ClientPublicInterface<T> extends MyPackagePrivateInterface<T, Void> {
}
My reasoning is this:我的理由是这样的:
computations based on user input, may create new Type allocations, that your system may need.基于用户输入的计算可能会创建您的系统可能需要的新类型分配。
The action may KEEP its namesake since in the eyes of the client it is performing what it is saying, but in sublayers within the system an equivalent action is taking place but with completely different Types, Types which ONLY your system should be aware.该动作可能会保持其同名,因为在客户端的眼中它正在执行它所说的内容,但是在系统内的子层中正在发生等效的动作,但具有完全不同的类型,只有您的系统应该知道的类型。
This may relate to a principle of "Self similarity" in which a system is composed of smaller components similar to itself, so it may be logical to reuse interfaces with different Types and similar namesake, this system also implies that reification (transforming something abstract into real) is intrinsical to the System state hence the user is not interested in an immediate reading of a return value, but the aim relies on the Object's change of state.这可能与“自相似”原则有关,其中系统由与其自身相似的较小组件组成,因此重用具有不同类型和相似名称的接口可能是合乎逻辑的,该系统还意味着具体化(将抽象的东西转换为real) 是系统状态固有的,因此用户对立即读取返回值不感兴趣,但目标依赖于对象的状态变化。
Now this particular example is for atomic operations, and TBH I cannot think of a different situation in which this may be needed, the reason being that native atomic operations are reliant in time-space(space = memory scope) snapshots for them to perform accurately.现在这个特定示例是针对原子操作的,TBH 我想不出可能需要这样做的不同情况,原因是本机原子操作依赖于时空(空间 = 内存范围)快照才能准确执行.
This new allocations are not important to the client but only to the system's functionality.这种新的分配对客户来说并不重要,而只对系统的功能很重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.