我写了一个固定的文件。
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;
}
}
}
1条答案
按热度按时间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已经在您希望的时候初始化了。因此:康斯坦特说唱歌手根本不应该存在。
如果你必须有一个原因,而不是在你的问题,这是如何做到这一点:
这正好实现了您想要的(即,只有一个示例,并且直到需要时才初始化这个示例),但是现在代码更少,没有bug。
常量表达式必需错误
方法调用不能是常量表达式周期。来源:java语言规范。
在声明时初始化的静态和最终字段,其类型是基元或字符串,而不是
null
如果初始化表达式是常量,则为常量表达式。就这样结束了。所以,这是可行的:甚至像这样
static final int A = 5, B = 10, C = A + B;
是允许的(C
这里也是常量,因为编译器可以在编译时计算出来),但编译器不会走得太远。无法将方法调用作为常量表达式计算,也无法判断
switch
接受非常量表达式。