Java 开关编译错误
我已经看了其他的问题,但仍然无法理解。为什么不让我用switch语句编译这段代码呢?我得到的错误是典型的错误“case表达式必须是常量表达式”。我正在尝试打开消息中的字节。由于速度问题,我想使用该开关,并尽量不进行任何转换,即从int到byte的转换。我的Utils类包含一个枚举PID,其中包含A、B、C。我想打开这些,但我得到的信息是以字节为单位的Java 开关编译错误,java,byte,switch-statement,bytebuffer,Java,Byte,Switch Statement,Bytebuffer,我已经看了其他的问题,但仍然无法理解。为什么不让我用switch语句编译这段代码呢?我得到的错误是典型的错误“case表达式必须是常量表达式”。我正在尝试打开消息中的字节。由于速度问题,我想使用该开关,并尽量不进行任何转换,即从int到byte的转换。我的Utils类包含一个枚举PID,其中包含A、B、C。我想打开这些,但我得到的信息是以字节为单位的 public class SomeClass extends Thread { public static final byte myCa
public class SomeClass extends Thread {
public static final byte myCase1 = (byte) Utils.PID.A.ordinal();
public static final byte myCase2 = (byte) Utils.PID.B.ordinal();
public static final byte myCase3 = (byte) Utils.PID.C.ordinal();
private double[] findAllData(ByteBuffer message) {
byte[] byteBuffer = new byte[9000];
// parse through and find all PIDs
for(int i=0 ;i < message.capacity(); i++) {
message.position(i);
switch (message.get(i)) {
case myCase1 : break; // Compiler errors at the case statements
case myCase2 : break;// Compiler errors at the case statements
case myCase3 : break;// Compiler errors at the case statements
}
}
}
// Utility class
public class Utils {
public enum PID { A,B,C };
}
public类SomeClass扩展线程{
公共静态最终字节myCase1=(字节)Utils.PID.A.ordinal();
公共静态最终字节myCase2=(字节)Utils.PID.B.ordinal();
公共静态最终字节myCase3=(字节)Utils.PID.C.ordinal();
专用双[]findAllData(ByteBuffer消息){
byteBuffer=新字节[9000];
//解析并查找所有PID
对于(int i=0;i
case语句必须是编译时常量。您需要预先计算(byte)Utils.PID.A.ordinal();
(和其他两个常量),然后硬编码它们的值。case语句必须是编译时常量。您需要预先计算(byte)Utils.PID.A.ordinal();
(和其他两个常量)然后硬编码它们的值。即使myCase1
是一个常量,但在编译时它不是已知的常量
相反,我会打开枚举
private static final Utils.PID[] PIDS = Utils.PID.values();
private double[] findAllData(ByteBuffer message) {
byte[] byteBuffer = new byte[9000];
// parse through and find all PIDs
for (int i = 0; i < message.capacity(); i++) {
message.position(i);
switch (PIDS[message.get(i)]) {
case A:
break;
case B:
break;
case C:
break;
}
}
尽管
myCase1
是一个常量,但它在编译时不是已知的常量
相反,我会打开枚举
private static final Utils.PID[] PIDS = Utils.PID.values();
private double[] findAllData(ByteBuffer message) {
byte[] byteBuffer = new byte[9000];
// parse through and find all PIDs
for (int i = 0; i < message.capacity(); i++) {
message.position(i);
switch (PIDS[message.get(i)]) {
case A:
break;
case B:
break;
case C:
break;
}
}
这里也讨论了这一点:复制以确保在发布编译器错误时始终发布完整的错误消息,或者在询问引发运行时异常时始终发布堆栈跟踪。@JPM:您编辑的示例绝对无法编译。您试图在实例中设置
static final
字段这是不允许的。所以我认为没有人能解释“为什么它有效”因为它显然不是。这里也讨论了这一点:复制以确保在发布编译器错误时始终发布完整的错误消息,或者在询问引发运行时异常时始终发布堆栈跟踪。@JPM:您编辑的示例绝对无法编译。您正试图设置静态final实例构造函数中的code>字段是不允许的。所以我认为没有人能解释“为什么它会工作”,因为它显然不是。这不是我在实例化类时所做的吗?常量是由以下行创建的:静态最终字节myCase3=(byte)Utils.PID.C.ordinal()@JPM,编译器对其求值太复杂了。请参阅我的example.JPM,这是在运行时发生的。编译文件时,大小写值必须是常量。实例化类时,我不就是这样做的吗?常量是由以下行创建的:静态最终字节myCase3=(byte)Utils.PID.C.ordinal();@JPM,它太复杂了,编译器无法计算。请参阅我的example.JPM,它发生在运行时。编译文件时,大小写值必须是常量。因此,请向我解释为什么当您不在类中设置它,而是在运行时在构造函数中设置它时,它会工作,但编译器对它没有问题?请参阅上文中的编辑question@JPM:你的前任示例已损坏,请参阅我对您的问题的评论。嗯,Eclipse中一定有bug…在编辑器中显示良好,但当我清除代码时,它会出错。删除了该代码示例。您的示例确实有效,但让我想知道为什么编译器无法处理它,对于编译器来说似乎足够简单。但这可能是对wiki的另一个讨论。@JPM,在中很简单理论上,但实际上它相当复杂,因为编译器不会对方法调用返回的结果进行任何假设。例如,Object.getClass()返回Class
而不是Class
,即编译器不知道此方法返回的是什么,即使它知道调用它的引用类型。因此,请向我解释为什么当您不在类中设置它,而是在构造函数中的运行时设置它时,它会工作,但编译器对此没有问题?请参阅上文中的编辑estion@JPM:您的示例已损坏,请参阅我对您的问题的评论。嗯,Eclipse中一定有bug…在编辑器中显示良好,但当我清除代码时,它会出错。删除了该代码示例。您的示例确实有效,但让我想知道为什么编译器无法处理它,这对编译器来说似乎足够简单。但这可能是wiki的另一个讨论。@JPM,它在理论上很简单,但在实践中却相当复杂,因为编译器对方法调用返回的内容不做任何假设。例如,Object.getClass()返回Class
,而不是Class
,也就是说,编译器不知道这个方法返回什么,即使它知道调用它的引用类型。