返回一个Void对象


113

Void如果不是原始类型,返回类型的正确方法是什么?例如。我目前使用null如下。

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

class A implements B<Void>{

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

1
我正在使用解释器模式编写文件格式的解释器,但某些表达式没有返回值
Robert

2
无法实例化Void类型,因此,如果您确实必须返回该类型的东西,则null是您唯一的选择。但是,您可能不需要任何返回值,因此null应该没问题。
乔恩2010年

是的,那也是我的逻辑-只是想知道是否还有一种更语义的方式
罗伯特·罗伯特(Robert

1
我会像您的示例一样编写代码。那是个好方法。
David Roussel

Answers:


134

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

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

  • 参数化Object并返回new Object()null
  • 参数化Void并返回null
  • NullObject您的一个参数化

你不能让这种方法void,和其他任何回报的东西。由于忽略了某些内容,因此您可以返回任何内容。


2
那么实现void返回类型的一般正确方法是什么?
罗伯特2010年

1
如果您想将null返回为void,则在某些情况下需要进行强制转换:(Void)null
Patrick Favre

return (Void)null;
亚历克斯R

(Void)null是否可以通过任何方式与null区分?
Orangle

13

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批注)结合使用时,此功能特别强大。


5
我认为这是朝错误的方向发展。最好返回一个更受约束的类型,以更清楚地传达含义。由于Optional<Void>您给出的相同原因,没有必要返回返回值的东西,因此您总是会得到一个Optional<Void>空值,因此所有其他方法都是毫无意义的。这与为什么要使用可选值相反。您使用它是因为它可能没有值。而且,编译器无法强制method()实施正确实现的代码。这将在运行时失败:return Optional.of(null)
steinybot

3

如果您只是不需要任何类型,可以使用void。这可以用于实现功能或动作。然后,您可以执行以下操作:

interface Action<T> {
    public T execute();
}

abstract class VoidAction implements Action<Void> {
    public Void execute() {
        executeInternal();
        return null;
    }

    abstract void executeInternal();
}

或者,您可以省略抽象类,并在不需要您自己返回值的每个操作中执行return 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
    }
});

2
这与我已有的有什么不同?就像我建议的那样,它仍然只是返回null
Robert

您为什么还要退还其他东西?我要说明的一点是,您不需要返回值,因此返回的内容无关紧要。我试图通过编辑来澄清这一点。
乔恩2010年

1

仅出于此目的,当然可以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.
        }
    }
}

您可能不会在生产中这样做。


0

没有通用类型可以告诉编译器方法什么也不返回。

我相信惯例是在继承作为类型参数时使用Object

要么

传播type参数,然后让类的用户使用Object实例化并将该对象分配给使用type-wildcard输入的变量?

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

class A<T> implements B<T>{

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

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

1
这是使用泛型将返回类型设置为void的惯例-对我来说看起来不是很无效吗?
罗伯特2010年

我相信这是要走的路。类的任何用户A<?>将无法使用的返回值method()
Christopher Oezbek,2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.