Java Void 引用类型的用途?

发布于 2024-07-14 23:08:09 字数 479 浏览 10 评论 0原文

有一个 Java Void -- 大写 V-- 引用类型。 我见过的唯一使用情况是参数化 Callable s

final Callable<Void> callable = new Callable<Void>() {
            public Void call() {
                foobar();
                return null;
            }
        };

Java Void 引用类型还有其他用途吗? 除了 null 之外,还可以为它分配任何其他值吗? 如果是的话,你有例子吗?

There is a Java Void -- uppercase V-- reference type. The only situation I have ever seen it used is to parameterize Callables

final Callable<Void> callable = new Callable<Void>() {
            public Void call() {
                foobar();
                return null;
            }
        };

Are there any other uses for the Java Void reference type? Can it ever be assigned anything other than null? If yes, do you have examples?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

花辞树 2024-07-21 23:08:09

Void 已成为您不感兴趣的泛型参数的约定。您没有理由应该使用任何其他不可实例化类型,例如 System

它也经常用于 Map 值(尽管 Collections.newSetFromMap 使用 Boolean 因为地图不必接受 null值)和java.security.PrivilegedAction

Void has become convention for a generic argument that you are not interested in. There is no reason why you should use any other non-instantiable type, such as System.

It is also often used in for example Map values (although Collections.newSetFromMap uses Boolean as maps don't have to accept null values) and java.security.PrivilegedAction.

苦笑流年记忆 2024-07-21 23:08:09

您可以使用反射创建 Void 实例,但它们没有任何用处。 Void 是一种指示泛型方法不返回任何内容的方法。

Constructor<Void> constructor = Void.class.getDeclaredConstructor();
constructor.setAccessible(true);
Void v = constructor.newInstance();
System.out.println("I have a " + v);

打印类似的东西

I have a java.lang.Void@75636731

You can create instance of Void using reflections, but they are not useful for anything. Void is a way to indicate a generic method returns nothing.

Constructor<Void> constructor = Void.class.getDeclaredConstructor();
constructor.setAccessible(true);
Void v = constructor.newInstance();
System.out.println("I have a " + v);

prints something like

I have a java.lang.Void@75636731
嘴硬脾气大 2024-07-21 23:08:09

Future 就像魅力一样。 :)

Future<Void> works like charm. :)

年华零落成诗 2024-07-21 23:08:09

鉴于没有公共构造函数,我会说它不能被分配除null之外的任何东西。 正如您的示例所示,我仅将其用作“我不需要使用此通用参数”的占位符。

它也可以用于反射,从它的 Javadoc< /a> 说:

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

Given that there are no public constructors, I would say it can't be assigned anything other than null. I've only used it as a placeholder for "I don't need to use this generic parameter," as your example shows.

It could also be used in reflection, from what its Javadoc says:

The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword void.

桃气十足 2024-07-21 23:08:09

所有原始包装类(IntegerByteBooleanDouble 等)都包含对静态TYPE字段中对应的原始类,例如:

Integer.TYPE == int.class
Byte.TYPE == byte.class
Boolean.TYPE == boolean.class
Double.TYPE == double.class

Void最初被创建为放置对void类型的引用的地方:

Void.TYPE == void.class

但是,使用 Void.TYPE 并没有真正获得任何好处。 当您使用 void.class 时,您会更清楚地知道您正在使用 void 类型执行某些操作。

顺便说一句,上次我尝试时,BeanShell 无法识别void.class,所以你必须在那里使用 Void.TYPE

All the primitive wrapper classes (Integer, Byte, Boolean, Double, etc.) contain a reference to the corresponding primitive class in a static TYPE field, for example:

Integer.TYPE == int.class
Byte.TYPE == byte.class
Boolean.TYPE == boolean.class
Double.TYPE == double.class

Void was initially created as somewhere to put a reference to the void type:

Void.TYPE == void.class

However, you don't really gain anything by using Void.TYPE. When you use void.class it's much clearer that you're doing something with the void type.

As an aside, the last time I tried it, BeanShell didn't recognise void.class, so you have to use Void.TYPE there.

泡沫很甜 2024-07-21 23:08:09

当您使用访问者模式时,当您想要确保返回值时,使用 Void 而不是 Object 会更简洁will be null

示例

public interface LeavesVisitor<OUT>
{
   OUT visit(Leaf1 leaf);

   OUT visit(Leaf2 leaf);
}

当您要实现访问者时,您可以显式地将 OUT 设置为 Void,以便您知道访问者将始终返回 null,而不是使用 Object

public class MyVoidVisitor implements LeavesVisitor<Void>
{
    Void visit(Leaf1 leaf){
        //...do what you want on your leaf
        return null;
    }

    Void visit(Leaf2 leaf){
        //...do what you want on your leaf
        return null;
    }
}

When you use the visitor pattern it can be cleaner to use Void instead of Object when you want to be sure that the return value will be null

Example

public interface LeavesVisitor<OUT>
{
   OUT visit(Leaf1 leaf);

   OUT visit(Leaf2 leaf);
}

When you will implement your visitor you can explicitly set OUT to be Void so that you know your visitor will always return null, instead of using Object

public class MyVoidVisitor implements LeavesVisitor<Void>
{
    Void visit(Leaf1 leaf){
        //...do what you want on your leaf
        return null;
    }

    Void visit(Leaf2 leaf){
        //...do what you want on your leaf
        return null;
    }
}
走走停停 2024-07-21 23:08:09

在泛型之前,它是为反射 API 创建的,用于保存 Method.getReturnType() 返回的 void 方法的 TYPE,对应于其他基本类型类。

编辑:来自 Void 的 JavaDoc:“Void 类是一个不可实例化的占位符类,用于保存对表示 Java 关键字 void 的 Class 对象的引用”。 在使用泛型之前,我知道除了反射之外没有其他用处。

Before generics, it was created for the reflection API, to hold TYPE returned by Method.getReturnType() for a void method, corresponding to the other primitive type classes.

EDIT: From the JavaDoc of Void: "The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword void". Prior to Generics, I am aware of no use other than reflection.

唱一曲作罢 2024-07-21 23:08:09

由于无法实例化 Void,因此可以使用 Apache commons Null 对象,因此

Null aNullObject = ObjectUtils.Null;
Null noObjectHere = null;

在第一行中,您有一个对象,因此 aNullObject != null 成立,而在第二行中没有引用,所以 noObjectHere == null 成立

回答发帖人原来的问题,这样做的用途是区分“无”和“无”,这是完全不同的东西。

PS:对空对象模式说不

As you can't instantiate Void, you can use Apache commons Null object, so

Null aNullObject = ObjectUtils.Null;
Null noObjectHere = null;

in the first line, you have an object, so aNullObject != null holds, while in the second line there is no reference, so noObjectHere == null holds

To answer the poster's original question, the usage for this is to differentiate between "the nothing" and "nothing", which are completely different things.

PS: Say no to Null object pattern

雅心素梦 2024-07-21 23:08:09

Void 的创建是为了包装其原始 void 类型。 每个基本类型都有其对应的引用类型。 Void 用于实例化泛型类或使用泛型方法、您不感兴趣的泛型参数。这是一个示例...

public void onNewRegistration() {
    newRegistrationService.createNewUser(view.getUsername(), view.getPassword(),
            view.getInitialAmount(), view.getCurrency(), new AsyncCallback<Void>() {
      @Override
      public void onFailure(Throwable caught) {
          
      }

      @Override
      public void onSuccess(Void result) {
        eventBus.fireEvent(new NewRegistrationSuccessEvent());
      }
    });
  } 

这里,如您所见,我不 感兴趣想要从服务器获取任何我要求创建新注册的内容,但是公共接口 AsyncCallback{ .... } 是一个泛型接口,因此我提供 Void 因为泛型不接受原始类型

Void was created to wrap its primitive void type. Every primitive type has its corresponding Reference type. Void is used to instantiate a generic class or use of a generic method, a generic argument which you are not interested in. Here is an example...

public void onNewRegistration() {
    newRegistrationService.createNewUser(view.getUsername(), view.getPassword(),
            view.getInitialAmount(), view.getCurrency(), new AsyncCallback<Void>() {
      @Override
      public void onFailure(Throwable caught) {
          
      }

      @Override
      public void onSuccess(Void result) {
        eventBus.fireEvent(new NewRegistrationSuccessEvent());
      }
    });
  } 

Here, as you can see, I don't want anything from the server that I am asking to create a new registration ,but public interface AsyncCallback<T> { .... } is a generic interface, so i provide Void since generics don't accept primitive types

沙沙粒小 2024-07-21 23:08:09

当您不需要 Attachment 对象时,它也常用于异步 IO 完成回调。 在这种情况下,您可以为 IO 操作指定 null 并实现 CompletionHandler

It is also commonly used on Async-IO completion callbacks when you dont have the need for an Attachment object. In that case you specify null to the IO operation and implement CompletionHandler<Integer,Void>.

吻泪 2024-07-21 23:08:09

这可能是罕见的情况,但有一次,我在方面类中使用了Void

这是一个在具有 @Log 注释的方法之后运行的方面,如果方法返回类型不为 void,则记录返回的方法和一些信息。

 @AfterReturning(value = "@annotation(log)", 
       returning = "returnValue", 
       argNames = "joinPoint, log, returnValue"
      )
    public void afterReturning(final JoinPoint joinPoint, final Log log,
            final Object returnValue) {

            Class<?> returnType = ((MethodSignature) joinPoint.getSignature())
            .getReturnType();
           if (Void.class.isAssignableFrom (returnType)) ) {
            //Do some log
         }
}

It may be rare case but once, I used Void in aspect classes.

This was an aspect which runs after methods that has an @Log annotation, and logs the method returned and some info if the method return type is not void.

 @AfterReturning(value = "@annotation(log)", 
       returning = "returnValue", 
       argNames = "joinPoint, log, returnValue"
      )
    public void afterReturning(final JoinPoint joinPoint, final Log log,
            final Object returnValue) {

            Class<?> returnType = ((MethodSignature) joinPoint.getSignature())
            .getReturnType();
           if (Void.class.isAssignableFrom (returnType)) ) {
            //Do some log
         }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文