简体   繁体   English

切换语句并在静态块中初始化最终的静态变量

[英]Switch statement and initializing a final static variable in static block

For my project, I have many objects split into 10 classes. 对于我的项目,我有很多对象分为10个类。 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. 为每个类定义的操作表示为public final static整数。 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). 我想在运行时动态分配操作的ID(每个类的操作数目前约为20,数字将增加)。

The problem arises, when an operation is performed and I have to find which operation is being performed (I use a switch statement). 问题出现了,当执行操作并且我必须找到正在执行的操作时(我使用switch语句)。

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 . 此代码通常编译并显示BAR

But this slightly transformed code produces an Unresolved compilation problem with case expressions must be constant expressions . 但是这个稍微改变的代码会产生一个Unresolved compilation problemcase 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. 我们有两个枚举,我希望有一个处理函数(最好使用switch语句),它可以处理这两个枚举中出现的所有情况。

EDIT2: So here goes. 编辑2:所以这里。 I have 10 classes (C1, C2, ..., C10) and around 40 objects of these classes. 我有10个类(C1, C2, ..., C10)和这些类的大约40个对象。 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). 每个共享对象都有一个所有者(这是基本关系 - 它与java继承没有任何关系)。

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). 现在每个共享对象obj变化不时,这obj需要向它的主人own ,如果它可能会改变(这只是其中一个操作),然后它改变(并再次通知业主)。 Object obj also has a predefined set of operations which he may perform, defined in C1 by an enum . 对象obj还具有他可以执行的预定义操作集,在C1enum定义。 Hence own has to have a handling function for object operations of class C1 . 因此, own必须具有C1类对象操作的处理功能。 Now we have an object obj2 which is of class C2 , has a different set of operations and the same owner own . 现在我们有一个对象obj2 ,它是C2类,有一组不同的操作,同一个所有者own obj may perform only operations defined in C1 and obj2 may perform only operations defined in C2 . obj可以仅执行在C1定义的操作,并且obj2可以仅执行在C2定义的操作。

How to generalize the handling function so it will be neatly written? 如何概括处理功能,以便整齐地编写? Should I even use enums? 我应该使用枚举吗?

You can only use constants known at compile time in a switch statement. 您只能在switch语句中使用编译时已知的常量。 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. 但由于这些值直到运行时才知道,因此无法构建switch语句或检查它是否正确。

static variables or blocks or methods are loaded at the time of Class initialization(Runtime). 在类初始化(运行时)时加载static variables or blocks or methods

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. 在第一种情况下, foobar值在编译时是已知的。

I recommend using enums for that. 我建议使用枚举。 This way the ID handling is not neccessary anymore. 这样就不再需要ID处理了。

public class Test {
  enum Operation {
    FOO, BAR, THESE, ARE, ALL, DIFFERENT, OPERATIONS
  }

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

    for (Operation op:ops)
      handleOperation(op);
  }

  public static void handleOperation(Operation op) {
    switch(op) {
    case FOO:
      System.out.println("FOO");
      break;
    case BAR:
      System.out.println("BAR");
      break;
    case THESE:
      System.out.println("THESE");
      break;
    case ARE:
      System.out.println("ARE");
      break;
    case ALL:
      System.out.println("ALL");
      break;
    case DIFFERENT:
      System.out.println("DIFFERENT");
      break;
    case OPERATIONS:
      System.out.println("OPERATIONS");
      break;
    default:
      System.out.println("PROBLEM");
    }
  }
}

OR simply use a if-elseif case : 或者只是使用if-elseif案例:

private final static int ONE = 1;
private final static int TWO = 2;

public static void main(String[] args) {
int value = 1;

  if(value==ONE){

  }
  else if(value==TWO){

  }

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM