【问题标题】:Variable initialization inside enum, or preventing enum with missing cases in compile time枚举内的变量初始化,或防止枚举在编译时缺少案例
【发布时间】:2015-08-01 22:34:15
【问题描述】:

我遇到了一个变量问题,该变量在枚举的开关中被初始化。似乎Android Studio(和Eclipse)忽略了我在所有案例中初始化变量并声明:“变量'x'可能尚未初始化”。我不想设置默认情况。

代码示例:

public enum  eTest {
    One,
    Two
}


public class Test {
    public void method(eTest value) {
        String toPrint;

        switch (value) {
            case One:
                toPrint = "One";
                break;
            case Two:
                toPrint = "Two";
                break;
        }

        System.out.println(toPrint); // <-- said error
    }
}

我不想初始化变量,但我不确定是否有办法在不初始化的情况下执行此操作(我希望喜欢知道我错了)。 假设这是不可能的,我想确保将新的枚举值添加到此开关中。

第一次尝试:
I've tried adding the "Enum 'switch' statement that misses case" to the Android Studio settings,但这有两个问题:

  1. 它不会使构建失败(仅显示带有红色标记的位置)。
  2. 这取决于本地配置,我希望可以对所有用户强制执行。

第二次尝试:
我发现使用 build.gradle 文件中的 lintOptions 应该可以做到这一点(如前所述,我使用的是 Android Studio),但是我无法使其按预期工作。我在 build.gradle 中添加了以下选项:

lintOptions {
    enable 'EnumSwitchStatementWhichMissesCases'
    abortOnError true
}

这并不奏效,我假设是因为两个可能的问题:

  1. 名称错误(我取自 Android Studio 在使用设置时创建的 xml)。
  2. 此问题的默认严重性是警告而不是错误,但是我找不到如何更改问题的严重性。

第三次尝试:
It should be possible to add a lint.xml to the Android Studio project,我也试过了,但它并没有使构建失败,所以我假设我在那里做错了什么。我将以下内容放在 AndroidManifest 位置:

<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <issue id="EnumSwitchStatementWhichMissesCases" severity="error" />
</lint>

此外:
我见过this answer,但这不是我要找的,而且由于这是一个特定的构建过程,我希望有更好的解决方案。

问题:
是否可以:

1. 解决原来的问题。 编辑:这无法完成(感谢 Blackbelt - 请参阅下面的评论)
如果不是:罢工>
2. 将上述选项添加到构建过程中(欢迎任何可以对其他用户强制执行的选项)。

编辑: 澄清 - 我想知道如何在 Android Studio 中使用 lint 来防止在编译时缺少案例的枚举

【问题讨论】:

  • “我发现使用 build.gradle 文件中的 lintOptions 应该可以实现这一点”——因为这不是来自 Android Lint,我对此表示怀疑。在您第一次尝试时,您在 Android Studio 中配置的是 IntelliJ IDEA 检查,而不是来自 Android Lint 类别的检查。 “应该可以将 lint.xml 添加到 Android Studio 项目”——同样,这不是 Android Lint 检查。 Android Lint 专注于 Android(因此得名)。 enum 是一种通用的 Java 语言结构。
  • 你可以看看像the checkstyle plugin 这样的东西是否可以被配置为捕获这个东西并导致构建失败。
  • 要么在 switch 块中存在默认标签,要么在 switch 表达式之后 [un] 分配 V。Here
  • @CommonsWare 我很难理解您的评论,您指的是“EnumSwitchStatementWhichMissesCases”吗?另外,我认为如果可能的话,最好不要依赖插件,但如果没有其他解决方案,我肯定会研究它。不管怎样,谢谢!
  • 是的。这是一个 IntelliJ IDEA 的东西,Android Studio 继承了它,因为它基于 IDEA。这不是 Android Lint 或 Gradle 的事情,这就是为什么如果您可以使用“第二次尝试”和“第三次尝试”中的技术(使用您问题中的术语)配置它,我会感到震惊。跨度>

标签: android android-studio enums gradle lint


【解决方案1】:

此错误来自 Java 编译器,而不是来自 IntelliJ IDEA 检查或 Android linter。如果您使用命令行 Java 编译器编译常规 Java 类(非 Android),您将看到完全相同的错误。因此,您修复它的任何尝试都不起作用。 EnumSwitchStatementWhichMissesCases 检查检测到在这种情况下不会发生的不同类型的问题。

Java 编译器之所以将此报告为错误,是因为 Java 支持对类进行单独编译。即使现在您的 switch 涵盖了枚举的所有可能情况,枚举类也可能会在以后重新编译并包含其他条目,这些条目不会由您的 switch 处理。

因此,即使将未知的枚举条目传递给方法,您也需要确保变量已初始化。您可以通过在变量声明中添加初始化程序或向开关添加default 分支来实现(分支中的代码可能会简单地抛出错误)。

【讨论】:

  • 感谢您的回答,但我认为您正在回答第一个问题,而且 Blackbelt 在上面的 cmets 中已经确定了无法做到这一点的事实,我将把我的问题编辑为反映这一点。
【解决方案2】:

创建一个默认案例。

enum myEnum(one, two, error)
String toPrint;

switch (myEnum)
{
case(one):
toPrint = "one";
break;

case (two):
toPrint = "two";
break;

default:
toPrint = "error";
}

【讨论】:

  • 谢谢,但我提到我不想使用默认大小写。
  • 出于好奇,我想知道您为什么不想使用默认值,因为它不需要做任何事情。有什么收获?明白我在这里并没有反对。我真的很好奇。
  • 目标是强制使用所有枚举值并得到错误(编译时间),否则(如果稍后添加新的),默认情况不能解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-17
  • 2013-06-01
  • 1970-01-01
  • 2013-11-18
相关资源
最近更新 更多