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_Q
和 OPTIONS
确实有 初始化程序 。我最初声明将 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
作为标签。
给定布尔值和基于它的变量集:
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_Q
和 OPTIONS
确实有 初始化程序 。我最初声明将 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
作为标签。