开发者

Non-static variable in case expression?

开发者 https://www.devze.com 2023-02-16 21:08 出处:网络
I would like to access a public integer from another class for use in a switch statement as below: StateManager sm = new StateManager(0);

I would like to access a public integer from another class for use in a switch statement as below:

StateManager sm = new StateManager(0);

switch (localState) {
 开发者_StackOverflow中文版   case (sm.ALL_COMPANIES_REQUEST): {
       //do something 
    }
    case (sm.GENERAL_TICKER_REQUEST): {
       //do this instead    
    }

However, these variables need to be accessed by multiple threads, so I don't want to make them static. Unfortunately I am getting an error saying that case expressions must be constant. There are no methods that change these variables, they are constant, but it seems that without labeling them static the computer cannot figure that out. Anyone know how to get around this?

Edit: How about nesting the classes, this is an option as StateManager is really only useful to the class with the switch statement above. Would this be sufficient to use final alone?


The requirement is that the values on a switch statement are constant expressions or enum values; see JLS 14.11.

A constant expression is described in JLS 15.28. Essentially it is a compile time constant expression. So that means that something like this would not compile:

    static final int foo = someString.length();
    ...
    switch (x) {
        case foo: ...  // case label is not a >>compile time<< constant
    }

However, your concern about static constants and threads is unfounded. The specification of final fields specifically states that they can be safely read without synchronization; see JLS 17.5.

(Besides, you wouldn't get deadlocks even if the fields weren't final. What you would get would be threads possibly seeing stale values of the field if they didn't synchronize properly on the parent object or class.)

So the answer to your question is:

  • if the constant is a compile time constant, you can just declare is as static final and the switch statement will compile, but
  • if the constant is NOT a compile time constant, then declaring it as static final won't help.

How about nesting the classes?

That won't make any difference.


If they're constants there's no problem declaring them final static and using them in a case statement. Multi-threading has no impact here.


Why not declare these fields inside an enum?

enum Request { 

    ALL_COMPANIES,
    GENERAL_TICKER

}

and then use that in your switch.


try using final, that will make it constant.


Using static/static+final modifier on line before the switch is pressented.

void m(){
final int a = 0;

switch(e)
case a : ...

}

woudl not work because void m() will compile after all the static attrs/methods had compiled.

void m()
{
switch(e)
case a : ...
}

final int a = 0;

woudl not work because declaraton of "a" is after the switch

final int a = 0;

void m()
{
switch(e)
case a : ...
}

would work .

Same principle for

static A a = new A(b);
static B b = new B();

would not work because JVM builder is reading code line by line... its not as worse as in C/C++ but it still exists.

switch works on statics, final constants, enums... they doesnt work for hashSet entries (and that is one thing that makes me quite mad :D )

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号