我想从另一个类访问一个公共整数,以便在switch语句中使用,如下所示:
StateManager sm = new StateManager(0);
switch (localState) {
case (sm.ALL_COMPANIES_REQUEST): {
//do something
}
case (sm.GENERAL_TICKER_REQUEST): {
//do this instead
}
但是,这些变量需要由多个线程访问,所以我不想让它们成为静态的。不幸的是我收到一个错误,说case表达式必须是常量。没有方法可以改变这些变量,它们是不变的,但似乎没有标记它们static
,计算机就无法解决这个问题。有谁知道怎么解决这个问题?
编辑: 如何嵌套类,这是一个选项,因为StateManager实际上只对上面带有switch语句的类有用。这足以单独使用final吗?
答案 0 :(得分:5)
要求是switch语句中的值是常量表达式或枚举值;见JLS 14.11。
JLS 15.28中描述了一个常量表达式。基本上它是编译时常量表达式。所以这意味着这样的东西不会编译:
static final int foo = someString.length();
...
switch (x) {
case foo: ... // case label is not a >>compile time<< constant
}
但是,您对静态常量和线程的关注是没有根据的。最终字段的规范明确规定可以在没有同步的情况下安全地读取它们;见JLS 17.5。
(此外,即使字段不是最终的,你也不会遇到死锁。你会得到的是线程可能看到字段的陈旧值,如果它们没有正确同步的话父对象或类。)
所以问题的答案是:
static final
并且switch语句将编译,但是static final
将无济于事。如何嵌套类?
这不会有任何区别。
答案 1 :(得分:2)
如果它们是常量,则声明它们final static
并在case语句中使用它们没有问题。多线程在这里没有影响。
答案 2 :(得分:1)
为什么不在枚举中声明这些字段?
enum Request {
ALL_COMPANIES,
GENERAL_TICKER
}
然后在你的交换机中使用它。
答案 3 :(得分:1)
尝试使用final,这将使其保持不变。
答案 4 :(得分:0)
在提交开关之前使用静态/静态+最终修饰符。
void m(){
final int a = 0;
switch(e)
case a : ...
}
woudl无效,因为void m()将在所有静态attrs /方法编译后编译。
void m()
{
switch(e)
case a : ...
}
final int a = 0;
woudl不起作用,因为“a”的声明在切换之后
final int a = 0;
void m()
{
switch(e)
case a : ...
}
会奏效
的相同原则
static A a = new A(b);
static B b = new B();
不起作用,因为JVM构建器逐行读取代码...它不像C / C ++那样糟糕但它仍然存在。
开关适用于静态,最终常量,枚举...它们不适用于hashSet条目(这是让我非常生气的一件事:D)