首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 位元組陣列與基本型別轉換工具類完整實作

     編輯:Java 相關知識

前言

在網路通訊、二進位協定解析、檔案格式處理、加密演算法等場景,Java 基本型別 (byte, short, int, long) 與 byte[] 互轉是核心操作。本文提供一個生產級工具類,涵蓋**大端序 (Big-Endian / Network Byte Order)** 標準轉換、無符號處理、十六進位字串轉換,並解析關鍵位運算原理。

一、核心轉換原理:大端序與位運算

Java 基本型別皆為**有號** (最高位為符號位)。網路傳輸標準採用**大端序**:最高位元組在最低位址。

int (32位) → byte[4] 示意

int value = 0x12345678;  // 二進位: 00010010 00110100 01010110 01111000
                         // 記憶體佈局 (大端序):
byte[0] = (byte) 0x12;  // 最高位元組 (MSB) - 無符號 18
byte[1] = (byte) 0x34;  // 52
byte[2] = (byte) 0x56;  // 86
byte[3] = (byte) 0x78;  // 最低位元組 (LSB) - 無符號 120

關鍵位運算技巧

  • & 0xFF:將 byte (有號 -128~127) 轉為 **無符號 int (0~255)**,去除符號擴展影響。
  • >> n:算術右移 (保留符號位),用於有號數值位移。
  • >>> n:邏輯右移 (補 0),**處理無符號數值/位元組提取必用**。
  • << n:左移 (補 0),用於組合位元組。

二、完整工具類實作 (DataTypeConverter)

package com.example.util;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public final class DataTypeConverter {
    private DataTypeConverter() {} // 工具類禁止實例化

    // ============ 基本型別 → byte[] (大端序) ============

    /** byte → byte[1] */
    public static byte[] toBytes(byte value) {
        return new byte[] { value };
    }

    /** short (16位) → byte[2] */
    public static byte[] toBytes(short value) {
        return new byte[] {
            (byte) ((value >>> 8) & 0xFF),  // 高位元組
            (byte) (value & 0xFF)           // 低位元組
        };
    }

    /** int (32位) → byte[4] */
    public static byte[] toBytes(int value) {
        return new byte[] {
            (byte) ((value >>> 24) & 0xFF),
            (byte) ((value >>> 16) & 0xFF),
            (byte) ((value >>> 8) & 0xFF),
            (byte) (value & 0xFF)
        };
    }

    /** long (64位) → byte[8] */
    public static byte[] toBytes(long value) {
        return new byte[] {
            (byte) ((value >>> 56) & 0xFF),
            (byte) ((value >>> 48) & 0xFF),
            (byte) ((value >>> 40) & 0xFF),
            (byte) ((value >>> 32) & 0xFF),
            (byte) ((value >>> 24) & 0xFF),
            (byte) ((value >>> 16) & 0xFF),
            (byte) ((value >>> 8) & 0xFF),
            (byte) (value & 0xFF)
        };
    }

    // ============ byte[] → 基本型別 (大端序) ============

    /** byte[1] → byte */
    public static byte toByte(byte[] bytes, int offset) {
        return bytes[offset];
    }

    /** byte[2] → short (有號) */
    public static short toShort(byte[] bytes, int offset) {
        return (short) (
            ((bytes[offset] & 0xFF) << 8) |
            ((bytes[offset + 1] & 0xFF))
        );
    }

    /** byte[2] → int (無符號 short, 0~65535) */
    public static int toUnsignedShort(byte[] bytes, int offset) {
        return ((bytes[offset] & 0xFF) << 8) |
               ((bytes[offset + 1] & 0xFF));
    }

    /** byte[4] → int (有號) */
    public static int toInt(byte[] bytes, int offset) {
        return ((bytes[offset] & 0xFF) << 24) |
               ((bytes[offset + 1] & 0xFF) << 16) |
               ((bytes[offset + 2] & 0xFF) << 8) |
               ((bytes[offset + 3] & 0xFF));
    }

    /** byte[4] → long (無符號 int, 0~4294967295) */
    public static long toUnsignedInt(byte[] bytes, int offset) {
        return ((((long) bytes[offset] & 0xFF) << 24) |
                (((long) bytes[offset + 1] & 0xFF) << 16) |
                (((long) bytes[offset + 2] & 0xFF) << 8) |
                (((long) bytes[offset + 3] & 0xFF))) & 0xFFFFFFFFL;
    }

    /** byte[8] → long (有號) */
    public static long toLong(byte[] bytes, int offset) {
        return ((((long) bytes[offset] & 0xFF) << 56) |
                (((long) bytes[offset + 1] & 0xFF) << 48) |
                (((long) bytes[offset + 2] & 0xFF) << 40) |
                (((long) bytes[offset + 3] & 0xFF) << 32) |
                (((long) bytes[offset + 4] & 0xFF) << 24) |
                (((long) bytes[offset + 5] & 0xFF) << 16) |
                (((long) bytes[offset + 6] & 0xFF) << 8) |
                (((long) bytes[offset + 7] & 0xFF)));
    }

    // ============ 便利方法:ByteBuffer 版 (自動處理位序、邊界檢查) ============

    /** 使用 ByteBuffer 寫入 int (預設大端序) */
    public static byte[] toBytesBB(int value) {
        return ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(value).array();
    }

    /** 使用 ByteBuffer 讀取 int */
    public static int toIntBB(byte[] bytes, int offset) {
        return ByteBuffer.wrap(bytes, offset, 4).order(ByteOrder.BIG_ENDIAN).getInt();
    }

    // ============ 十六進位字串轉換 ============

    /** byte → 兩位十六進位字串 (如 0x0A → "0A") */
    public static String toHex(byte b) {
        return String.format("%02X", b & 0xFF);
    }

    /** byte[] → 十六進位字串 (可選分隔符) */
    public static String toHexString(byte[] bytes, String separator) {
        StringBuilder sb = new StringBuilder(bytes.length * 3);
        for (int i = 0; i < bytes.length; i++) {
            if (i > 0 && separator != null) sb.append(separator);
            sb.append(String.format("%02X", bytes[i] & 0xFF));
        }
        return sb.toString();
    }

    /** 十六進位字串 → byte[] (支援可選分隔符) */
    public static byte[] fromHexString(String hex, String separator) {
        String clean = (separator == null) ? hex : hex.replace(separator, "");
        if (clean.length() % 2 != 0) throw new IllegalArgumentException("Hex string length must be even");
        byte[] bytes = new byte[clean.length() / 2];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt(clean.substring(i * 2, i * 2 + 2), 16);
        }
        return bytes;
    }

    // ============ 無符號 byte 處理 ============

    /** byte → 無符號 int (0~255) */
    public static int unsignedByteToInt(byte b) {
        return b & 0xFF;
    }
}

三、單元測試驗證

import org.junit.Test;
import static org.junit.Assert.*;

public class DataTypeConverterTest {

    @Test
    public void testIntRoundTrip() {
        int[] cases = {0, 1, -1, 127, -128, 32767, -32768, 0x7FFFFFFF, 0x80000000, -123456789};
        for (int val : cases) {
            byte[] bytes = DataTypeConverter.toBytes(val);
            int result = DataTypeConverter.toInt(bytes, 0);
            assertEquals(val, result);
        }
    }

    @Test
    public void testLongRoundTrip() {
        long[] cases = {0L, 1L, -1L, Integer.MAX_VALUE, Integer.MIN_VALUE, 0x7FFFFFFFFFFFFFFFL, 0x8000000000000000L};
        for (long val : cases) {
            byte[] bytes = DataTypeConverter.toBytes(val);
            long result = DataTypeConverter.toLong(bytes, 0);
            assertEquals(val, result);
        }
    }

    @Test
    public void testUnsignedInt() {
        // 0xFFFFFFFF 作為有號 int 是 -1,無符號為 4294967295
        byte[] bytes = DataTypeConverter.toBytes(-1); // 全 1
        long unsigned = DataTypeConverter.toUnsignedInt(bytes, 0);
        assertEquals(0xFFFFFFFFL, unsigned);
    }

    @Test
    public void testHexConversion() {
        byte[] data = {0x01, 0x23, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF};
        String hex = DataTypeConverter.toHexString(data, " ");
        assertEquals("01 23 AB CD EF", hex);
        
        byte[] parsed = DataTypeConverter.fromHexString(hex, " ");
        assertArrayEquals(data, parsed);
    }

    @Test
    public void testByteBufferEquivalence() {
        int val = 0x12345678;
        byte[] manual = DataTypeConverter.toBytes(val);
        byte[] bb = DataTypeConverter.toBytesBB(val);
        assertArrayEquals(manual, bb);
        
        assertEquals(val, DataTypeConverter.toIntBB(bb, 0));
    }
}

四、效能比較與選擇建議

方法效能可讀性安全性適用場景
手動位運算⭐⭐⭐⭐⭐ (最快)⭐⭐⭐⭐ (需自行檢查邊界)極高頻呼叫、嵌入式、協定解析核心路徑
ByteBuffer⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ (內建邊界檢查、位序切換)一般業務、可維護性優先、需支援小端序
DataOutputStream⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐寫入檔案/網路流串流場景

五、常見坑點提醒

  1. 符號擴展:byte b = (byte) 0xFF; int i = b; → i == -1。必須用 b & 0xFF 取得 255。
  2. 位移運算優先級:b << 24 會先將 byte 提升為 int 再位移,若 b 為負數會符號擴展。**必須先 & 0xFF 再位移**:(b & 0xFF) << 24。
  3. 陣列越界:手動位運算版本**不檢查陣列長度**,生產環境建議加入 if (bytes.length < offset + 4) throw new IllegalArgumentException(...)。
  4. 長度不固定:short 2 字節、int 4 字節、long 8 字節,切勿混用。

結語

掌握位元組與基本型別轉換的位運算本質,是處理二進位協定、高效能序列化、硬體介接的核心技能。建議專案中**統一封裝工具類**,優先使用 ByteBuffer 保證正確性與可維護性,僅在經效能分析確認的熱點路徑改用手動位運算優化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved