返回一个“空”物体

如果 Void类型不是原语,那么返回它的正确方法是什么?艾格。我当前使用 null,如下所示。

interface B<E>{ E method(); }


class A implements B<Void>{


public Void method(){
// do something
return null;
}
}
138508 次浏览

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

因此,以下任何一项就足够了:

  • 使用 Object参数化并返回 new Object()null
  • 使用 Void参数化并返回 null
  • 用你的 NullObject参数化

你不能让这个方法返回 void,其他的方法返回 什么的。因为这个方法被忽略了,所以你可以返回任何东西。

没有泛型类型会告诉编译器方法什么也不返回。

我相信约定是在继承类型参数时使用 Object

或者

向上传播 type 参数,然后让类的用户使用 Object 实例化对象,并将对象分配给使用 type 通配符 ?类型化的变量:

interface B<E>{ E method(); }


class A<T> implements B<T>{


public T method(){
// do something
return null;
}
}


A<?> a = new A<Object>();

如果您不需要任何类型的东西,可以使用 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
}
});

Java8引入了一个新类 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注释)一起使用时,这种功能特别强大。

仅仅为了这个目的,当然有可能使用反射创建 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.
}
}
}

你可能不会这样做,在生产。

如果更改安全管理器,就有可能创建 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的一个实例。

我找到了一种获取 Void 类实例的新方法。这是 env分配 Void 对象的本机代码。然后对象被返回到 java 代码。该对象存在于 Java 代码中,可作为实际实例使用。

JNIEXPORT jobject JNICALL Java_main_Main_getVoid(JNIEnv *env, jobject obj){
jclass voidclass=env->FindClass("java/lang/Void");
return env->AllocObject(voidclass);
}