«Отсутствует оператор возврата» после switch (enum) - Почему? - PullRequest
0 голосов
/ 02 мая 2018

Компилятор утверждает, что в конце 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 {
}

Прав ли компилятор? (Android Studio)

Если так, при каких обстоятельствах может быть достигнут конец метода? Я думаю, что myEnum не может быть null, и все перечисления включены в оператор switch, где в любом случае оператор return покинет метод. myEnum не может быть null, потому что метод @NonNull MyEnum.parse() выдает исключение, если результат null.

Если нет, вы бы отметили (надеюсь) недоступный конец метода с помощью return null // should never be reached или бросили AssertionError?

1 Ответ

0 голосов
/ 02 мая 2018

Правильный ли компилятор?

Да, потому что он не проверяет покрытие enum во время компиляции. Скажем, enum жил в другом двоичном файле и был обновлен новой константой. Что вернет метод?

myEnum не может быть null, потому что метод @NonNull MyEnum.parse() выдает исключение, если результат null.

Компилятор не достаточно умен, чтобы понять это (хотя ваша IDE может быть). Но это спорный вопрос, потому что включение null приведет к NPE.

Если нет, вы бы отметили (надеюсь) недоступный конец метода с помощью return null // should never be reached или бросили AssertionError?

Бросок AssertionError довольно условен. В качестве альтернативы рассмотрим встраивание условной логики в константы перечисления вместо использования переключателя.

...