表达式中的非静态变量?

时间:2011-03-12 05:42:41

标签: java static switch-statement

我想从另一个类访问一个公共整数,以便在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吗?

5 个答案:

答案 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)