4

我有一个简单的方法,它接受一个枚举并返回一个字符串:

public static String enumToString(MyEnum type) {
    return switch (type) {
        case Enum1 -> "String_1";
        case Enum2 -> "String_2";
        case Enum3 -> "String_3";
        case Enum4 -> "String_4";
        case Enum5 -> "String_5";
        case Enum6 -> "String_6";
        default -> null;
    };
}

但是声纳给了我这个主要错误:Unused method parameters should be removed

如您所见,参数类型在开关中使用。有关更多详细信息,当我使用旧开关盒时,一切都很好。

关于这个问题的任何想法,声纳是否涵盖新的 Java 语法?


嗯,我注意到当我default -> null;正确移除声纳通道时!这很奇怪。

public static String enumToString(MyEnum type) {
    return switch (type) {
        case Enum1 -> "String_1";
        case Enum2 -> "String_2";
        case Enum3 -> "String_3";
        case Enum4 -> "String_4";
        case Enum5 -> "String_5";
        case Enum6 -> "String_6";
        //default -> null;
    };
}
4

2 回答 2

2

这不是一个错误,Sonar 正确评估如果列表是详尽的,则switch 表达式永远不会落入default分支。

另一方面,如果您决定不列出所有可能的枚举常量,default则必须声明分支。否则,代码将无法编译,因为要求每个枚举常量都可以匹配。

注意:您的代码包含 switch 表达式,而不是 switch 语句。

于 2021-10-19T13:30:57.870 回答
1

从技术上讲,语法default -> null;不是“参数”。JLS将switch 块中的各种组件称为“规则”、“标签”或“表达式”;而相关的JEP也使用了“条款”一词。

无论您如何称呼它的组件,Switch表达式都不同于旧的 Switch语句。特别是,开关表达式是详尽无遗的。

来自 JEP,

穷举

switch 表达式的用例必须是详尽的;对于所有可能的值,必须有一个匹配的开关标签。(显然 switch 语句不需要是详尽的。)

在实践中,这通常意味着需要一个默认条款;但是,enum switch对于涵盖所有已知常量的表达式,编译器会插入一个默认子句,以指示枚举定义在编译时和运行时之间已更改。依靠这种隐式的默认子句插入可以得到更健壮的代码;现在,当重新编​​译代码时,编译器会检查所有情况是否都被显式处理。如果开发人员插入了一个明确的默认子句(就像今天的情况),一个可能的错误将被隐藏。

Sonar 足够聪明,可以知道何时涵盖了所有基础,这使得默认子句不仅无法访问,而且会干扰上述行为。

于 2021-10-19T13:31:04.003 回答