当Void
类型不是原始类型时,返回interface B<E>{ E method(); }
class A implements B<Void>{
public Void method(){
// do something
return null;
}
}
类型的正确方法是什么?例如。我目前使用null如下。
{{1}}
答案 0 :(得分:115)
Void类是一个不可实例化的占位符类,用于保存对表示Java关键字void的Class对象的引用。
所以以下任何一项都足够了:
Object
进行参数设置并返回new Object()
或null
Void
进行参数设置并返回null
NullObject
参数化你不能使这个方法void
,而其他任何东西都会返回某些东西。由于忽略了某些东西,你可以退货。
答案 1 :(得分:9)
Java 8引入了一个新类Optional<T>
,可以在这种情况下使用。要使用它,您可以按照以下方式稍微修改代码:
interface B<E>{ Optional<E> method(); }
class A implements B<Void>{
public Optional<Void> method(){
// do something
return Optional.empty();
}
}
这使您可以确保始终从方法中获得非空返回值,即使没有任何要返回的内容也是如此。当与检测何时可以或不能返回null
的工具结合使用时,这种功能特别强大,例如Eclipse @NonNull
和@Nullable
注释。
答案 2 :(得分:3)
如果您不需要任何类型的东西,可以使用void。这可用于实现功能或操作。然后你可以做这样的事情:
interface Action<T> {
public T execute();
}
abstract class VoidAction implements Action<Void> {
public Void execute() {
executeInternal();
return null;
}
abstract void executeInternal();
}
或者您可以省略抽象类,并在每个不需要返回值的操作中返回null。
然后你可以使用这样的行为:
给出方法
private static <T> T executeAction(Action<T> action) {
return action.execute();
}
你可以称之为
String result = executeAction(new Action<String>() {
@Override
public String execute() {
//code here
return "Return me!";
}
});
或者,对于void操作(请注意,您没有将结果分配给任何内容)
executeAction(new VoidAction() {
@Override
public void executeInternal() {
//code here
}
});
答案 3 :(得分:0)
没有泛型类型会告诉编译器方法什么都不返回。
我认为惯例是在继承为类型参数时使用Object
OR
向上传播类型参数,然后让类的用户使用Object实例化并将对象分配给使用类型 - 通配符?
键入的变量:
interface B<E>{ E method(); }
class A<T> implements B<T>{
public T method(){
// do something
return null;
}
}
A<?> a = new A<Object>();
答案 4 :(得分:0)
仅出于此目的,当然可以使用反射来创建Void
实例:
interface B<E>{ E method(); }
class A implements B<Void>{
public Void method(){
// do something
try {
Constructor<Void> voidConstructor = Void.class.getDeclaredConstructor();
voidConstructor.setAccessible(true);
return voidConstructor.newInstance();
} catch (Exception ex) {
// Rethrow, or return null, or whatever.
}
}
}
您可能不会在生产中这样做。
答案 5 :(得分:0)
如果您更改安全管理器,则可以创建 Void
的实例,如下所示:
static Void getVoid() throws SecurityException, InstantiationException,
IllegalAccessException, InvocationTargetException {
class BadSecurityManager extends SecurityManager {
@Override
public void checkPermission(Permission perm) { }
@Override
public void checkPackageAccess(String pkg) { }
}
System.setSecurityManager(badManager = new BadSecurityManager());
Constructor<?> constructor = Void.class.getDeclaredConstructors()[0];
if(!constructor.isAccessible()) {
constructor.setAccessible(true);
}
return (Void) constructor.newInstance();
}
显然这不是那么实用或安全;但是,如果您能够更改安全管理器,它将返回一个 Void
实例。