Build.VERSION.SDK_INT 是常量表达式吗?

Is Build.VERSION.SDK_INT constant expression?

给定布尔值和基于它的变量集:

private static final boolean IS_ANDROID_Q = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
private static final int OPTION = IS_ANDROID_Q ? 0 : 1;

有一个 switch-case 语句:

public static void foo(int option) {
    switch (option) {
        case OPTION: break;
    }
}

编译器抱怨 constant expression required 变量 OPTION 错误。但是,当我将 Build.VERSION.SDK_INT 更改为其他 int 值时,它没有显示任何错误消息。

official documentation 声明 Build.VERSION.SDK_INT 声明为 static final int

oracle documentation 中指定的常量表达式外,是否还需要任何条件?

还是我漏掉了什么?

更新 1:

我认为这个 post 没有解决我的问题的原因是

private static final boolean IS_ANDROID_Q = {with some int} >= Build.VERSION_CODES.Q;
private static final int OPTION = IS_ANDROID_Q ? 0 : 1;

这运行得很好。

更新 2:

有人提到 Java switch statement: Constant expression required, but it IS constant 可能是这个问题的解决方案,我不同意。如果你看一下这个问题的公认答案,他说

... the Foo.BA* variables do not have initializers, and hence do not qualify as "constant variables". ...

但是如您所见,我声明的变量 IS_ANDROID_QOPTIONS 确实有 初始化程序 。我最初声明将 Build.VERSION.SDK_INT 更改为某个常量 int 值导致构建成功。

所以剩下的唯一问题是Build.VERSION.SDK_INT是否是常量表达式。给出一个基本原理,常量表达式只有在用编译时常量表达式初始化时才有效。您可以在我上面链接的问题中找到它。

这就是我将这个问题命名为"Is Build.VERSION_SDK_INT constant expression?"的全部原因。与我的变量是否初始化无关

因此,我不认为这个问题是重复的。

我搜索了 source code for Android SDK 并确认 Build.VERSION.SDK_INT 不是常量表达式。

这里是Build.VERSION.SDK_INT的定义:

public static final int SDK_INT = SystemProperties.getInt(
        "ro.build.version.sdk", 0);

Build.VERSION.SDK_INT 不是常量表达式,因为它是非常量变量的简单名称。 A constant variable 只能用常量表达式初始化。常量表达式不能将函数调用作为其初始化语句的一部分,这里我们看到了对 SystemProperties.getInt(..) 的调用。

因此,您不能在 switch 语句和其他只接受常量表达式的地方使用 Build.VERSION.SDK_INT 作为标签。