给定布尔值和基于它的变量集:
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;
有一个开关案例语句:
public static void foo(int option) {
switch (option) {
case OPTION: break;
}
}
编译器抱怨constant expression required
变量OPTION
错误。但是,当我Build.VERSION.SDK_INT
更改为其他 int 值时,它没有显示任何错误消息。
官方文件指出Build.VERSION.SDK_INT
被声明为static final int
.
除 oracle 文档中指定之外,常量表达式是否需要任何条件?
还是我错过了什么?
更新 1:
我认为这篇文章没有解决我问题的原因是
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语句:需要常量表达式,但它是常量可能是这个问题的解决方案,我不同意。如果你看一下这个问题的公认答案,他说
。Foo.BA* 变量没有初始值设定项,因此不符合"常量变量"的条件。...
但是,如您所见,我声明的变量IS_ANDROID_Q
和OPTIONS
确实具有初始值设定项。我最初表示,将Build.VERSION.SDK_INT
更改为某个恒定的int
值导致了成功的构建。
因此,唯一剩下的问题是Build.VERSION.SDK_INT
是否是一个常量表达式。为了给出一个基本原理,常量表达式只有在使用编译时常量表达式初始化时才有效。你可以在我上面链接的问题中找到这个。
这就是我将这个问题命名为"Build.VERSION_SDK_INT
是恒定表达式吗?这与我的变量是否已初始化无关。
因此,我不认为这个问题是重复的。
Build.VERSION.SDK_INT
不是常量表达式,因为它是非常量变量的简单名称。常量变量只能使用常量表达式进行初始化。常量表达式不能包含函数调用作为其初始化语句的一部分,这里我们看到对SystemProperties.getInt(..)
的调用。
因此,不能在 switch 语句和其他仅接受常量表达式的地方使用Build.VERSION.SDK_INT
作为标签。
我搜索了Android SDK的源代码,并确认Build.VERSION.SDK_INT
不是常量表达式。
以下是Build.VERSION.SDK_INT
的定义:
public static final int SDK_INT = SystemProperties.getInt(
"ro.build.version.sdk", 0);