将方法返回类型赋给case时出现java常量表达式必需错误

ttvkxqim  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(405)

我写了一个固定的文件。

public interface IConstants {

    int SOME_CONSTANT = 6;
}

我已经编写了一个 Package 器方法来访问constantwrapper文件中的“some\ constant”变量

public class ConstantWrapper {

   static ConstantWrapper mConstantWrapper = null;

    private ConstantWrapper(){

    }

    public static ConstantWrapper getInstance(){
        if(mConstantWrapper == null)
            mConstantWrapper = new ConstantWrapper();

        return mConstantWrapper;
    }

    public int getSomeConstantValue(){
        return IConstants.SOME_CONSTANT;
    }
}

现在,我想访问switch case语句中的 Package 器方法,但得到错误“constant expression required”。如何解决?

public class DemoClass{

private void checkSwitchCases(int value) {

        switch (value){
            case ConstantWrapper.getInstance().getSomeConstantValue(): // I get the error "constant expression required" in this line
                System.out.println("Case 6");
                break;

            case 8:
                System.out.println("Case 8");
                break;

            default:
                System.out.println("Case default");
                break;
        }
    }

}
hjzp0vay

hjzp0vay1#

你在这里应用各种反模式。看起来您遇到了一个问题(这里:我有一些要管理的常量),并决定了解决您的问题的方法(一个接口+一个您错误地称为“ Package 器”的类),现在您正在进一步询问有关您在实现解决方案时遇到的问题的问题。但是,这不是一个好的解决方案,所以让我们回到原来的问题。
我写了一个固定的文件
把一堆常量塞进一个接口以前是很常见的,但是现在我们有了枚举是星型导入,这不再是推荐的方法。只要把常量放在它们最相关的地方(不太可能是一个接口,但如果必须的话,好吧),然后使用 import static com.foo.ThatType.*; 在一个想要使用它们的类中。不要 implements 你的 IConstants anywhere—类的类型层次结构是公共信息,应该说明一些关于结构的信息,以及 IConstants 是毫无意义的,这就是为什么这是糟糕的风格。 IConstants 不建议使用这种匈牙利符号变体。如果发现某个类型是接口或类,ide完全能够通知您这些信息是否相关。您不应该在编写代码的时候就把这一点放在第一位:为什么 IName 事情是反模式的。 class ConstantWrapper 这有什么用?你已经签了一大堆的工作,来维持你的职业。我可以推测的唯一真正的好处是,您可以选择插入一个替代实现,但这意味着这些常量实际上并不是常量,因此您得到的错误是正确的,解决方法是不使用 switch 总之,不要用“常量”这个词。把一个有很多角的东西叫做“圆”是个坏主意。命名很难,但很重要。 public static ConstantWrapper getInstance() 您没有应用双重锁定,这意味着您可以有2个或更多ConstantRapper示例。如果必须动态加载一个类,则应该依赖类加载器。但是,使用 getInstance 实际初始化的方法:java不会在引导时加载所有类;它只在第一次使用时加载一个类。考虑到第一次使用 ConstantWrapper 将会是 .getInstance() ,java已经在您希望的时候初始化了。因此:
康斯坦特说唱歌手根本不应该存在。
如果你必须有一个原因,而不是在你的问题,这是如何做到这一点:

public class ConstantWrapper {
    private static final ConstantWrapper INSTANCE = new ConstantWrapper();
    public static ConstantWrapper getInstance() {
        return INSTANCE;
    }
}

这正好实现了您想要的(即,只有一个示例,并且直到需要时才初始化这个示例),但是现在代码更少,没有bug。
常量表达式必需错误
方法调用不能是常量表达式周期。来源:java语言规范。
在声明时初始化的静态和最终字段,其类型是基元或字符串,而不是 null 如果初始化表达式是常量,则为常量表达式。就这样结束了。所以,这是可行的:

class Example {
    public static final int FOO = 5;
}

class Foo {
    {
        switch (value) {
            case Example.FOO: // allowed; this is a constant expression
            case 10: // allowed; this is constant too
        }
    }
}

甚至像这样 static final int A = 5, B = 10, C = A + B; 是允许的( C 这里也是常量,因为编译器可以在编译时计算出来),但编译器不会走得太远。
无法将方法调用作为常量表达式计算,也无法判断 switch 接受非常量表达式。

相关问题