Java Void 引用类型的用途?
Posted
技术标签:
【中文标题】Java Void 引用类型的用途?【英文标题】:Uses for the Java Void Reference Type? 【发布时间】:2010-10-13 05:38:48 【问题描述】:有一个 Java Void
-- 大写 V-- reference type。我见过它使用的唯一情况是参数化Callable
s
final Callable<Void> callable = new Callable<Void>()
public Void call()
foobar();
return null;
;
Java Void
引用类型还有其他用途吗?除了null
,它还能被分配任何东西吗?如果有,你有例子吗?
【问题讨论】:
dzone.com/articles/why-does-void-class-exist-jdk 在Java8中,新增功能:use Function interface to replace Consumer or Supplier 【参考方案1】:Void
已成为您不感兴趣的通用参数的约定。没有理由应该使用任何其他不可实例化类型,例如 System
。
它也经常用于例如Map
值(尽管Collections.newSetFromMap
使用Boolean
,因为地图不必接受null
值)和java.security.PrivilegedAction
。
【讨论】:
谁制定了这个约定?文档状态docs.oracle.com/javase/tutorial/java/generics/types.html“类型参数命名约定按照约定,类型参数名称是单个大写字母。” @barlop 这是参数而不是参数名称。也就是说,它是java.lang.Void
类型。 / 乔什·布洛赫 (Josh Bloch) 推广了该约定,尽管一旦您看到它,它就是显而易见的选择。
该博客条目已失效【参考方案2】:
您可以使用反射创建 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
【讨论】:
+1 用于实例化文档中说不可实例化的类。我也这样做了,我同意实例化的 Void 是没用的。 构造函数System.exit(0)
)。我倾向于使用private Void() throw new Error();
的构造函数编写实用程序类。有些人可能更喜欢无值枚举。【参考方案3】:
Future<Void>
就像魅力一样。 :)
【讨论】:
使用Future<?>
更为常见(例如,在 Guava 中),因为未来通常会有一个合法值(非Void
类型),但在不使用的上下文中使用'不在乎价值。
CompletableFuture<Void>
的作用也是一种魅力。【参考方案4】:
鉴于有no public constructors,我会说它不能被分配除null
以外的任何东西。如您的示例所示,我仅将其用作“我不需要使用此通用参数”的占位符。
它也可以用于反射,从它的Javadoc 所说:
Void 类是一个不可实例化的占位符类,用于保存对表示 Java 关键字 void 的 Class 对象的引用。
【讨论】:
有趣的是,Oracle/Sun 如此描述它,因为 null 是所有类型的实例。无论如何,正如你所说,它的纯粹含义是“我可以在这里写任何类型,因为我对它不感兴趣,所以我会放 Void 以确保阅读我的代码的人完全理解这一点”【参考方案5】:所有原始包装类(Integer
、Byte
、Boolean
、Double
等)在静态 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
。
【讨论】:
所以既有 Void.class 又有 void.class!【参考方案6】:当您使用visitor pattern 时,如果您想确保返回值为空,则使用 Void 而不是 Object 会更简洁
例子
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;
【讨论】:
【参考方案7】:在泛型之前,它是为反射 API 创建的,用于保存 Method.getReturnType() 返回的 TYPE,用于 void 方法,对应于其他原始类型类。
编辑:来自 Void 的 JavaDoc:“Void 类是一个不可实例化的占位符类,用于保存对表示 Java 关键字 void 的 Class 对象的引用”。在泛型之前,我知道除了反射没有其他用途。
【讨论】:
我不相信这个。现在我面前没有 1.4 或更早的 JVM,但我相信 Method.getReturnType() 总是为 void 方法返回 void.class。 @Pour:我是说 before 泛型,我知道的唯一用途是保存 TYPE(如在 Void.TYPE 中),它在反射的方法中使用.getReturnType() 用于 void 方法。 它不知何故不返回Void
。请看***.com/questions/34248693/…【参考方案8】:
由于不能实例化Void,所以可以使用Apache commons Null object,所以
Null aNullObject = ObjectUtils.Null;
Null noObjectHere = null;
在第一行,你有一个对象,所以aNullObject != null
成立,而在第二行没有引用,所以noObjectHere == null
成立
为了回答发帖者的原始问题,这个的用法是区分“无”和“无”,它们是完全不同的东西。
PS:对 Null 对象模式说不
【讨论】:
【参考方案9】: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());
);
在这里,如您所见,我不希望服务器提供任何我要求创建新注册的东西,但public interface AsyncCallback<T> ....
是一个通用接口,所以我提供Void
因为泛型不接受原始类型
【讨论】:
【参考方案10】:当您不需要 Attachment
对象时,它也常用于 Async-IO 完成回调。在这种情况下,您将 IO 操作指定为 null 并实现 CompletionHandler<Integer,Void>
。
【讨论】:
【参考方案11】:这可能很少见,但有一次,我在方面类中使用了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
【讨论】:
以上是关于Java Void 引用类型的用途?的主要内容,如果未能解决你的问题,请参考以下文章