切换后的“缺少退货声明”(枚举) - 为什么?

时间:2018-05-02 20:10:23

标签: java enums compiler-errors

编译器声称MyClass.parse()末尾缺少return语句。这是代码:

package de.hs_rm.safelyovertaken.ble;

import android.support.annotation.NonNull;

import java.util.Arrays;

class MyClass {

    @NonNull
    static MyClass parse(byte[] encoded) throws MyParseException {

        MyEnum myEnum = MyEnum.parse(Arrays.copyOfRange(encoded, 0, 2));

        switch (myEnum) {
            case A:
                return new MyClassA();

            case B:
                return new MyClassB();

            case C:
                return new MyClassC();
        }

        // compile error: "Missing return statement"

//        return null; // should never be reached
//        throw new AssertionError("Should never be reached");
    }
}

enum MyEnum {
    A, B, C;

    @NonNull
    static MyEnum parse(byte[] encoded) throws MyParseException {

        MyEnum result = null;

        // parse logic here

        if (result == null) {
            throw new MyParseException();
        }

        return result;
    }
}

class MyParseException extends Exception {
}

class MyClassA extends MyClass {
}

class MyClassB extends MyClass {
}

class MyClassC extends MyClass {
}

编译器是对的吗? (Android Studio)

如果是这样,在什么情况下可以达到方法的结束?我认为myEnum不能是null并且所有枚举都包含在switch语句中,其中return语句将离开该方法。 myEnum不能为null,因为如果结果为@NonNull,则MyEnum.parse()方法null会引发异常。

如果没有,您是否会使用return null // should never be reached标记(希望)无法访问的方法结束或抛出AssertionError

1 个答案:

答案 0 :(得分:9)

  

编译器是对的吗?

是的,因为它在编译时没有验证枚举覆盖率。假设枚举存在于另一个二进制文件中,并使用新常量进行更新。该方法会返回什么?

  

myEnum不能为null,因为如果结果为@NonNull,则MyEnum.parse()方法null会引发异常。

编译器不够聪明,无法解决这个问题(尽管你的IDE可能是这样)。但这不是一个有争议的问题,因为启用null会导致NPE。

  

如果没有,您是否会使用return null // should never be reached标记(希望)无法访问的方法结束或抛出AssertionError

投掷AssertionError非常传统。或者,考虑embedding conditional logic in the enum constants而不是使用开关。