0

Trying to implement a switch case statement for an enumeration that lives in another class. i have cleaned the useless code out of the way for you all. My problem occurs at the Second code segment at the second line.

My current guess is it doesn't like the casting to byte in the enumeration because it is trying to use that as the index. If this is the case, how do i go about getting the byte to an index to be tested? I should mention i'v used this technique once before but with standard integer casting. such that "value(1)," for instance. So i thought i understood the concept of how this is working? but now i'm second guessing myself and wound up stuck. i have tried to google the snot out of this problem but i keep coming up short.

Is a switch case possible on byte castings of an enumeration???, if so, can someone please help with enlightening my java skills, or please point me to a better method of testing my byte. preferably something other than if else statements? i just thought it looked neater with the switch statement.

EDIT: So i appear to understand the problem of outofbounds, but that doesn't answer the question of how do i go about fixing the outofbounds to still work with the byte enumeration that i currently have?? other than making a specific if statement for the -15?

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;
        }
    }
}

Here is the Switch case i am trying to accomplish. the error i get is "java.lang.ArrayIndexOutOfBoundsException: length=6; index=-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;
}
Mr.Invisible
  • 167
  • 2
  • 10
  • Possible duplicate of [What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?](http://stackoverflow.com/questions/5554734/what-causes-a-java-lang-arrayindexoutofboundsexception-and-how-do-i-prevent-it) – OH GOD SPIDERS Dec 23 '16 at 19:26

2 Answers2

0

It occurs because your ack_nak has value "-15". The problem is with your anotherClass.getDataByte() method or just use the code like this:

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;
}

If you want to use Enum, you may check all posible values of ack_nak by if-else statement.

Remember, you can't use non-constant expression in switch-case statement!

Edit:

There is one more solution. Your anotherClass.getDataByte() method should return the value of the Ack_Nak enum instead of byte. Then, you may use the code like this:

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;
}
Ihor Dobrovolskyi
  • 1,241
  • 9
  • 19
0

You seem to have a wrong idea of what OtherClass.Ack_Nak.values() will return.

It will simply return an array with all Possible values.

so OtherClass.Ack_Nak.values()[0] will contain OtherClass.Ack_Nak.ACK, OtherClass.Ack_Nak.values()[1] will contain OtherClass.Ack_Nak.NAK

And so on.

If you want to get the correct enum value that contains a specific byte value you have to write the logic for that yourself.

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
}

after that foundEnum will contain the corresponding enum value for the bytes you search and you can switch on it.

Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
OH GOD SPIDERS
  • 3,091
  • 2
  • 13
  • 16
  • AH!! this makes since!, i thought the switch case did the resulting search for me.. stupid me.. learned something new!! – Mr.Invisible Dec 23 '16 at 19:55