【问题标题】:Java switch/case vs if issueJava switch/case 与 if 问题
【发布时间】:2014-07-06 23:32:09
【问题描述】:

我一直在尝试使用 java 类来模拟 Stack。 这是我的类构造函数:

        public Stack(Class<?> type){

        if(type==String.class){

                //...

            }

            switch(type){

                    case (String.class):
                            //...
                    break;
                    case (Integer.class):
                            //...
                    break;

                    case (Double.class):
                            //...
                    break;

                    case (Byte.class):
                            //...
                    break;

                    default:
                    break;

            }

            this.counter = -1;

        }

但令我困惑的是, if 块工作正常。但是对于 switch/case 块,它不会编译。

错误提示

incompatible types
                switch(type){
                       ^
  required: int
  found:    Class

error: constant expression required
case (String.class):

这对 switch 块中的所有情况重复。

如果这里有什么遗漏,请指出我。

【问题讨论】:

  • 等等...编译器很清楚:switch 需要一个 int,但你传递的是一个 Class 对象
  • 如果这里有什么遗漏,请指点我。当然:Java Tutorials. The switch Statement.
  • 这里除了switch语句的错误用法,请问为什么会有这么奇怪的设计而不使用泛型?
  • @shan 尝试不同的方法是件好事,但这种方法会导致代码难以维护,并且无法为真实世界的应用程序准备好。你确定这就是你想要的吗?
  • @Luiggi Mendoza :哎呀......不过没想到那么远。 :(

标签: java class oop data-structures stack


【解决方案1】:

Java switch/case 仅适用于原语(byte、short、char 和 int)、Enums(from java 5) 和 String(from java 7) 数据类型。查看oracle教程here

与 if-then 和 if-then-else 语句不同,switch 语句可以 有许多可能的执行路径。开关与 byte、short、char 和 int 原始数据类型。它也适用于 枚举类型(在 Enum Types 中讨论)、String 类和一个 一些包装某些原始类型的特殊类:字符, 字节、短整数和整数(在数字和字符串中讨论)。

你可以像下面这样使用

switch(type.getName()){

  case ("java.lang.String"):
         //...
         break;
  ...
}

【讨论】:

  • 补充一下,ops可以参考this
  • @LUiggiMendoza :答案已更新。我虽然OP可以在答案的帮助下解决问题。我没有兴趣在不让他弄清楚解决方案的情况下给出答案
  • sigh... 请阅读问题中的 cmets 以了解真正的问题。
  • @LuiggiMendoza :当我回答这个问题时,没有 cmets 或答案。所以,我不过,他可以找出解决方案。
  • 我知道,但他们现在在你迟到的答案编辑之后:)。
【解决方案2】:

代码中的主要问题是switch 语句的错误使用。它仅适用于原始类型byteshortcharint常量(文字或final 标记变量)。从Java 5开始,它还允许这些原语的各个包装类的常量变量:ByteShortCharacterInteger,并且还支持enums,并且从Java 7开始它支持常量@ 987654335@ 变量。这在Java Tutorials. The switch Statement 中有介绍。因此,要修复您当前的代码,请使用 if 语句而不是 switch

//when comparing object references, use the equals method, not ==
if (String.class.equals(type)) {
    //...
} else if (Integer.class.equals(type)) {
    //...
} else ...

来自您的评论:

只需要为 Stack 构建一个可以使用多种数据类型的类设计。是不是我做错了什么?

设计的主要问题是您必须在这个长长的if 列表中添加基本上任何 Java 类和自定义类,这会使您的代码真的很丑、很糟糕甚至对你来说都是一场噩梦。为了解决这个问题,自 Java 5 起,Java 给了我们generics。所以,你可以这样定义你的类:

class MyStack<E> {
    //implementing the stack using a generic single linked list
    class Item {
        E data;
        Item next;
    }
    private Item head;
    private Item tail;
    private int size = 0;
    public MyStack() {
    }
    public int getSize() {
        return this.size;
    }
    public void add(E e) {
        Item temp = new Item();
        temp.data = e;
        if (head == null) {
            head = temp;
        } else {
            tail.next = temp;
        }
        tail = temp;
        size++;
    }
    //add the rest of the behavior...
}

顺便说一句,Java Collections API 中已经有一个Stack 类,你不应该有任何与Java JDK API 同名的类。这就是为什么在我的示例中,堆栈类称为MyStack

【讨论】:

  • 这很棒。就在这一点上。
【解决方案3】:

Switch-case 适用于原始、枚举和字符串(来自 java 7)数据类型。因此,在您的情况下,您可以使用返回 stringclass#getName,如果您使用的是 java 7。

switch(type.getName()){

  case ("java.lang.String"):
         //...
         break;
  case ("java.lang.Integer"):
         //...
         break;
  ...
}

【讨论】:

  • AFAIK String.class.getName() 给出java.lang.String
  • 这个答案需要 Java 7
  • 现在这不会编译,因为您必须设置编译器可以作为常量的值。 String.class.getName() 不是编译器的常量值。
【解决方案4】:

这意味着你不能在 switch 中使用类类型。 但是,如果您需要为不同的类类型执行此操作,只需使用默认值.. 就像

...
case 1: // for string class
break;
case 2: // for integer class
break; 
... and so on

【讨论】:

    【解决方案5】:

    我从口腔网站找到了这个。

    开关适用于 byte、short、char 和 int 原始数据 类型。它也适用于枚举类型(在枚举类型中讨论), String 类,以及一些包装某些特定类的特殊类 原始类型:Character、Byte、Short 和 Integer(在 数字和字符串)。

    【讨论】:

    • 什么是有意义的? OP如何用这个答案解决问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多