简体   繁体   English

java.lang.Void 和 void 有什么区别?

[英]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 对象的引用。”

  1. What is "uninstantiable" place holder class?什么是“不可实例化”的占位符类? When will java.lang.Void be used?什么时候使用java.lang.Void If the class is "uninstantiable", what use is it?如果类是“不可实例化的”,它有什么用?
  2. What is difference between java.lang.Void and void ? java.lang.Voidvoid有什么区别?

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 . intIntegerlongLongbyteByte ... 并且voidVoid 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.Voidvoid有什么区别?”

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.比如说,在 Android AsyncTaks<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.

相关问题 无法将void转换为java.lang.Void - Cannot convert void to java.lang.Void 为什么 java.lang.Void 不可序列化? - Why is java.lang.Void not Serializable? java.lang.Void vs void vs Null - java.lang.Void vs void vs Null Mockito问题 - 当Stubber中的(java.lang.Void)无法应用于void时 - Mockito issue - when(java.lang.Void) in Stubber cannot be applied to void Reactive Mongo - DeleteAllBy... 查询 - 找不到类型 class java.lang.Void 的 PersistentEntity - Reactive Mongo - DeleteAllBy… query - Couldn't find PersistentEntity for type class java.lang.Void 不兼容的类型。 找到:'javax.mail.PasswordAuthentication',需要:'java.lang.Void' - Incompatible types. Found: 'javax.mail.PasswordAuthentication', required: 'java.lang.Void' AsyncTask引发错误“由java.lang.ClassCastException引起:java.lang.Object []无法转换为doinbackground()上的java.lang.Void []” - AsyncTask throwing Error “Caused by java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.Void[]” on doinbackground() Java泛型中Void和无界通配符有什么区别? - what is the difference between Void and unbounded wildcard in Java generics? void方法和return this有什么区别 - What is the difference between void method and return this Void与无参数之间有什么区别? - What's the difference between Void and no parameter?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM