Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Switch statement and initializing a final static variable in static block

For my project, I have many objects split into 10 classes. Each of the objects may perform some operations, which have to be registered beforehand (the registering of operations is done only once per class). The operations defined for each class are represented as public final static integers. I would like to dynamically assign the ID of operations at runtime (the number of operations per class is currently about 20 and the number will increase).

The problem arises, when an operation is performed and I have to find which operation is being performed (I use a switch statement).

Here is a simple example of working code:

public class Test {
    final static int foo = 8;
    final static int bar = 10;

    public static void main(String[] args)
    {
        int x=10;

        switch(x)
        {
        case foo:
            System.out.println("FOO");
            break;
        case bar:
            System.out.println("BAR");
            break;
        default:
            System.out.println("PROBLEM");
        }
    }
}

This code normally compiles and displays BAR.

But this slightly transformed code produces an Unresolved compilation problem with case expressions must be constant expressions.

public class Test {
    final static int foo;
    final static int bar;

    static
    {
        foo=8;
        bar=10;
    }
    public static void main(String[] args)
    {
        int x=10;

        switch(x)
        {
        case foo:
            System.out.println("FOO");
            break;
        case bar:
            System.out.println("BAR");
            break;
        default:
            System.out.println("PROBLEM");
        }
    }
}

Shouldn't these codes actually work and compile the same? I am not able to do anything dynamically until I resolve this problem? Or is any other way?

Thanks

EDIT: Due to ideas for using enums I would like to solve this problem:

public class Test {
  enum OperationSet1 {
    FOO, BAR, THESE, ARE, ALL, DIFFERENT, OPERATIONS
  }
  enum OperationSet2 {
    FOO, BAR, NOW, SOME, OTHER, OPS
  }

  public static void main(String[] args) {
    OperationSet1[] ops = new OperationSet1[10];
    for (int i=0; i<ops.length; i++)
      ops[i] = OperationSet1.values()[(int)(Math.random()*OperationSet1.values().length)];

    OperationSet2[] ops2 = new OperationSet2[10];
    for (int i=0; i<ops.length; i++)
      ops[i] = OperationSet2.values()[(int)(Math.random()*OperationSet2.values().length)];

    for (OperationSet1 op:ops)
      handleOperation(op);
  }
    for (OperationSet2 op:ops2)
      handleOperation(op);
  }
  public static void handleOperation(Object? op) {
    switch(op) {
        /**code to handle**/
    }
  }
}

We have two enums and I would like to have one handling function (prefferably with switch statement), which would handle all the cases apperaing in these two enums.

EDIT2: So here goes. I have 10 classes (C1, C2, ..., C10) and around 40 objects of these classes. Some of these objects are so-called owners and some are shared. Each shared object has an owner (this is the basic relation - it does not have anything to do with java inheritance).

Now each of the shared objects obj changes from time to time, and this obj needs to ask its owner own if it may change (this is only one of the operations) and then it changes (and again notifies the owner). Object obj also has a predefined set of operations which he may perform, defined in C1 by an enum. Hence own has to have a handling function for object operations of class C1. Now we have an object obj2 which is of class C2, has a different set of operations and the same owner own. obj may perform only operations defined in C1 and obj2 may perform only operations defined in C2.

How to generalize the handling function so it will be neatly written? Should I even use enums?

like image 261
Nejc Avatar asked Sep 03 '12 13:09

Nejc


2 Answers

You can only use constants known at compile time in a switch statement. This is because switch code is checked and built statically.

In the second case you could do

static
{
    foo=8;
    bar=foo;
}

but as these values are not known until runtime, there would be no way to either built the switch statement or check it is correct.

like image 140
Peter Lawrey Avatar answered Sep 22 '22 03:09

Peter Lawrey


static variables or blocks or methods are loaded at the time of Class initialization(Runtime).

Your issue is at compilation time which is far before loading/intializing of class. So fields are final and they are not intialized (ofcourse at compile time).

While in 1st case, values of foo and bar are known at compile time.

like image 20
Nandkumar Tekale Avatar answered Sep 21 '22 03:09

Nandkumar Tekale