【问题标题】:How to do SwitchStatement on Enumeration with byte castings?如何使用字节转换对枚举进行 SwitchStatement?
【发布时间】:2016-12-23 19:15:18
【问题描述】:

尝试为存在于另一个类中的枚举实现 switch case 语句。我已经为大家清除了无用的代码。 我的问题出现在第二行的第二个代码段。

我目前的猜测是它不喜欢枚举中的字节转换,因为它试图将其用作索引。如果是这种情况,我该如何将字节获取到要测试的索引?我应该提到我以前使用过这种技术,但使用标准整数转换。例如“value(1)”。所以我想我理解这是如何工作的概念?但现在我第二次猜测自己并最终陷入困境。我试图用谷歌搜索这个问题的鼻涕,但我一直在做空。

在枚举的字节转换上是否可以使用 switch case???,如果是这样,有人可以帮助启发我的 java 技能,或者请指出一个更好的方法来测试我的字节。最好是 if else 语句以外的东西?我只是觉得 switch 语句看起来更整洁。

编辑: 所以我似乎理解出界的问题,但这并不能回答我如何着手修复出界以仍然使用我目前拥有的字节枚举的问题?除了为 -15 做一个特定的 if 语句之外?

public class OtherClass {
    public enum Ack_Nak{
        ACK((byte)0x01),
        NAK((byte)0x00),
        NAK_SIZE((byte)0x51),
        NAK_CRC((byte)0xCC),
        NAK_DATA((byte)0xD8),
        NAK_FILE((byte)0xF1);

        private final byte i;

        Ack_Nak(final byte i) {
            this.i = i;
        }
        public byte getByte() {
        return i;
        }
    }
}

这是我想要完成的 Switch 案例。我得到的错误是 “java.lang.ArrayIndexOutOfBoundsException:长度=6;索引=-15”

byte ack_nak = anotherClass.getDataByte();
OtherClass.Ack_Nak Ack_Naks = OtherClass.Ack_Nak.values()[ack_nak];  // Problem Here
switch (Ack_Naks) {
    case ACK:
        //do something here
        break;
    case NAK:
    case NAK_CRC:
    case NAK_DATA:
    case NAK_FILE:
    case NAK_SIZE:
    Toast.makeText(MainActivity.this,Ack_Naks.name() , Toast.LENGTH_SHORT).show();  //show failure
    //act on the failure here
        break;
    default:  //just incase
        break;
}

【问题讨论】:

标签: java android enums switch-statement byte


【解决方案1】:

这是因为您的 ack_nak 的值是“-15”。问题在于您的 anotherClass.getDataByte() 方法或仅使用如下代码:

byte ack_nak = anotherClass.getDataByte();
switch (ack_nak) {
    case 0x01:
        //do something here
        break;
    case 0x00:
    case 0x51:
    case 0xCC:
    case 0xD8:
    case 0xF1:
    Toast.makeText(MainActivity.this,Ack_Naks.name() , Toast.LENGTH_SHORT).show();  //show failure
    //act on the failure here
        break;
    default:  //just incase
        break;
}

如果要使用 Enum,可以通过 if-else 语句检查 ack_nak 的所有可能值。

请记住,您不能在switch-case 语句中使用非常量表达式!

编辑:

还有另一种解决方案。您的 anotherClass.getDataByte() 方法应该返回 Ack_Nak 枚举的值而不是字节。然后,您可以使用这样的代码:

Ack_Nak ack_nak = anotherClass.getDataByte();
switch (ack_nak) {
        case ACK:
            //do something here
            break;
        case NAK:
        case NAK_CRC:
        case NAK_DATA:
        case NAK_FILE:
        case NAK_SIZE:
            //act on the failure here
            break;
        default:  //just incase
            break;
}

【讨论】:

  • 所以从我想你所说的,是因为字节是-15,它超出了界限吗?尽管它是一个合法值,就像枚举中都存在的 51、CC 和 D8 一样?
  • 是的,它越界了。数组没有负索引。
  • 这是我必须能够测试我的字节并保持我的枚举的唯一选择吗??
  • 你也可以用try-catch检查异常。
【解决方案2】:

您似乎对 OtherClass.Ack_Nak.values() 将返回的内容有一个错误的想法。

它只会返回一个包含所有可能值的数组。

所以OtherClass.Ack_Nak.values()[0] 将包含OtherClass.Ack_Nak.ACKOtherClass.Ack_Nak.values()[1] 将包含 OtherClass.Ack_Nak.NAK

等等。

如果您想获得包含特定字节值的正确枚举值,您必须自己编写逻辑。

byte byteToSearch = anotherClass.getDataByte(); // the byte value to search
OtherClass.Ack_Nak foundEnum = null; // variable to hold the corresponding enum once we found it
for(OtherClass.Ack_Nak currentAckNak : OtherClass.Ack_Nak.values()) { // loop over all values
    if(currentAckNak.getByte() == byteToSearch) {
        foundEnum = currentAckNak; // if enums byte value in current iteration is the one we search for, we set the foundenum and break the loop
        break;
    }
}
if(foundEnum == null){
   throw new RuntimeException("No enum found for byte value: "+byteToSearch); // if foundEnum is still null we found no enum value for the byte and throw an exception
}

之后 foundEnum 将包含您搜索的字节的相应枚举值,您可以打开它。

【讨论】:

  • 啊!!这是因为!,我认为开关盒为我做了搜索..愚蠢的我..学到了一些新东西!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-14
相关资源
最近更新 更多