Java编译错误:枚举开关

3
我遇到了一个非常奇怪的错误,我无法解决。
一个在Windows上编译正常的项目,在Linux上编译时出现以下错误:
不能使用AClass.Bbb类型的值进行切换。只有可转换为int值、字符串或枚举变量的值是允许的
,尽管声明的类型枚举。
类的代码如下:
public class AClass {
    private enum Bbb {
        ONE,
        TWO;
    }
    public void aMethod(List<Bbb> arg) {
        for (Bbb en : arg) {
            switch (en) {
                ....
            }
        }
    }
}
switch(en)中的en被下划线标记,显示上述错误通知。
有人遇到过这个问题吗? 有没有解决方法? UPD Java版本:
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

1
这些机器上的Java版本怎么样? - Juvanis
1
错误提示显示类型值为 Aaa.Bbb。这是打错字了吗,还是你导入了不同的 Bbb? - trogdor
检查你的导入,你正在使用错误的导入方式来导入Bbb,Bbb不应该在你的导入列表中。 - Felquir
@trogdor 这是一个打字错误,我会纠正它。 - Ibolit
@Juvanis将Java版本信息添加到了帖子中。 - Ibolit
3个回答

3
如果您使用JDK1.7,问题应该会消失。请尝试按照以下步骤操作:
  1. 打开项目属性
  2. 点击“Java编译器”
  3. 勾选“启用项目特定设置”
  4. 将所有下拉菜单设置为1.7
  5. 点击“确定”
  6. 清除项目以触发重建
如果按照以下步骤操作,则问题会重新出现。
  1. 打开项目属性
  2. 点击“Java编译器”
  3. 清除“启用项目特定设置”
  4. 点击“确定”
  5. 清除项目以触发重建(它将自动重建)
如果按照以下步骤操作,我看到的是...
  1. 打开项目属性
  2. 点击“Java编译器”
  3. 点击“配置工作区设置”
  4. 我看到“编译器兼容性级别”=1.7
  5. 我看到“使用默认兼容性设置”已被勾选。
希望这能帮到您!

2
我尝试了您的代码。
public class AClass {
     enum Bbb {
        ONE,
        TWO;
    }
    public void aMethod(List<Bbb> arg) {
        for (Bbb en : arg) {
            switch (en) {

                case ONE: System.out.println("ONE");break;
                case TWO: System.out.println("TWO");break;
            }
        }
    }
    public static void main(String[] args) {

        List<Bbb> list = new ArrayList<Bbb>();
        list.add(Bbb.ONE);
        list.add(Bbb.TWO);

        new AClass().aMethod(list);
    }
}

它可以正常工作。
我不知道像这样传递参数List<Bbb> arg的利弊,但至少在我所知的Java 7中它并不会出错。


我知道它应该可以工作,在其他机器上也能工作,但在这台机器上却不行。 - Ibolit

2

我不知道这是否与Windows/Linux有关。但是

从JDK5开始,您可以在switch case中使用enum,而从JDK7开始,您可以在switch case中使用String。在使用enum时,请确保:

  1. 您正在使用JDK5及更高版本
  2. 您在switch中使用的所有标签必须是枚举中有效的enum对象。

在Java中,枚举通过类概念实现(每个Java中的enum都扩展到Enum类,该类是一个abstract类,并直接是Object类的子类)。因此,在创建枚举时,例如

 public enum Bbb {
        ONE,
        TWO;
    }

它在内部意味着:
public static final Bbb ONE=new Bbb();
public static final Bbb TWO=new Bbb();

意味着您定义的所有枚举对象都是公共的、最终的和静态的,属于定义的枚举类。如果您使用其他内容作为开关标签,它将在编译时出现错误。
对于Java中的每个枚举,超类Enum是final的,并且所有枚举类都在内部实现为final。因此,在Java中不能使用继承来处理枚举。这意味着我们不允许在开关标签中使用除我们自己的类枚举对象之外的任何内容(甚至不允许使用子类对象,因为枚举类不能进一步继承)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接