Are there any real life uses for the Java byte primitive type?

后端 未结 10 1729
清歌不尽
清歌不尽 2020-12-23 13:16

For some inexplicable reason the byte primitive type is signed in Java. This mean that valid values are -128..127 instead of the usual 0..255 range representin

10条回答
  •  南方客
    南方客 (楼主)
    2020-12-23 14:02

    byte has an extensive use in applet development for Java Card. Because cards have limited resources every bit of memory is precious. By the way card processors have limitations in processing of integer values. int type support is optional and java.lang.String is not supported so all integer operation and data storage is done by byte and short variables and arrays. As integer literals are of int type, they should be explicitly cast to byte or short in whole code. Communication with card goes through APDU commands that is handed to applet as an array of bytes that should be decomposed to bytes to decode command class, instruction and parameters. Looking at the following code you see how much byte and short types are important to Java Card development:

    package somepackage.SomeApplet;
    
    import javacard.framework.*;
    import org.globalplatform.GPSystem;
    import org.globalplatform.SecureChannel;
    
    public class SomeApplet extends Applet {
    
        // Card status
        private final static byte ST_UNINITIALIZED     = (byte) 0x01;
        private final static byte ST_INITIALIZED       = (byte) 0x02;
    
        // Instructions & Classes
        private final static byte PROP_CLASS           = (byte) 0x80;     
    
        private final static byte INS_INIT_UPDATE      = (byte) 0x50;
        private final static byte INS_EXT_AUTH         = (byte) 0x82;
    
        private final static byte INS_PUT_DATA         = (byte) 0xDA;
        private final static byte INS_GET_RESPONSE     = (byte) 0xC0;
        private final static byte INS_GET_DATA         = (byte) 0xCA;
    
    
        private final static short SW_CARD_NOT_INITIALIZED       = (short) 0x9101;  
        private final static short SW_CARD_ALREADY_INITIALIZED   = (short) 0x9102;  
    
        private final static byte OFFSET_SENT = 0x00;
        private final static byte OFFSET_RECV = 0x01;
        private static short[] offset;
    
        private static byte[] fileBuffer;
        private static short fileSize = 0;
    
        public static void install(byte[] bArray, short bOffset, byte bLength) {
            new SomeApplet( bArray, bOffset, bLength);
        }
    
        public RECSApplet(byte[] bArray, short bOffset, byte bLength) {
            offset = JCSystem.makeTransientShortArray((short) 2, JCSystem.CLEAR_ON_RESET);
            fileBuffer = new byte[FILE_SIZE];
    
            byte aidLen = bArray[bOffset];
            if (aidLen== (byte)0){
                register();
            } else {
                register(bArray, (short)(bOffset+1), aidLen);
            }
        }
    
        public void process(APDU apdu) {
            if (selectingApplet()) {
                return;
            }
            byte[] buffer = apdu.getBuffer();
            short len = apdu.setIncomingAndReceive(); 
    
            byte cla = buffer[ISO7816.OFFSET_CLA];
            byte ins = buffer[ISO7816.OFFSET_INS];
            short lc = (short) (buffer[ISO7816.OFFSET_LC] & 0x00ff); 
    
            while (len < lc) {
                len += apdu.receiveBytes(len);
            }
    
            SecureChannel sc = GPSystem.getSecureChannel();
            if ((short)(cla & (short)0x80) == ISO7816.CLA_ISO7816) {
                switch (ins) {
                    case INS_PUT_DATA:
                        putData(buffer, ISO7816.OFFSET_CDATA, offset[OFFSET_RECV], len);
    
                        if ((cla & 0x10) != 0x00) {
                            offset[OFFSET_RECV] += len;
                        } else {
                            fileSize = (short) (offset[OFFSET_RECV] + len);
                            offset[OFFSET_RECV] = 0;
                        }
                        return;
    
                    case INS_GET_DATA:
                    case INS_GET_RESPONSE:
                        sendData(apdu);
                        return;
                    default:
                        ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
                }
    
            }
            else if ((byte) (cla & PROP_CLASS) == PROP_CLASS) {
                switch (ins) {
                    case INS_INIT_UPDATE:
                    case INS_EXT_AUTH:
                        apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, sc.processSecurity(apdu));
                        return;
                    default:
                        ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
                }
            } else
                ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
        }
    
        // Some code omitted
    
    }
    

提交回复
热议问题