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

Tob*_*ann 3 java enums compiler-errors

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

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 {
}
Run Code Online (Sandbox Code Playgroud)

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

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

如果没有,你将标志着该方法的(希望)可达端return null // should never be reached或抛出AssertionError

shm*_*sel 9

编译器是对的吗?

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

myEnum不能是null因为如果结果是该@NonNull方法MyEnum.parse()抛出异常null.

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

如果没有,你将标志着该方法的(希望)可达端return null // should never be reached或抛出AssertionError

投掷AssertionError是非常传统的.或者,考虑在枚举常量中嵌入条件逻辑而不是使用开关.