杰瑞科技汇

Java byte转string有哪些方法?

核心概念:字符编码

计算机只认识 0 和 1。byte 类型就是 8 个 0 或 1 的组合,但如何将这些 0 和 1 解释成人类能读懂的字符(如 'A', '中', '€'),就需要一套“翻译规则”,这就是字符编码

Java byte转string有哪些方法?-图1
(图片来源网络,侵删)
  • ASCII: 最早的编码,只能表示英文字母、数字和一些符号,每个字符占 1 个字节。
  • ISO-8859-1 (Latin-1): 扩展了 ASCII,支持一些欧洲语言,每个字符也占 1 个字节。
  • GBK / GB2312: 中国国家标准编码,支持大部分中文字符,英文字符占 1 字节,中文字符占 2 字节。
  • Big5: 繁体中文编码。
  • UTF-8: 目前互联网上最通用的编码,它是可变长度的,英文字符占 1 字节,中文通常占 3 字节,其他复杂字符可能占更多字节。强烈推荐在所有新项目中使用 UTF-8。

关键点:将 byte[] 转为 String 时,你必须告诉 Java 你使用的是哪种编码,否则它会使用 JVM 的默认编码,这在不同操作系统或环境下可能导致乱码。


单个 byteString

如果你只有一个 byte,想把它转换成一个表示其十六进制值的字符串,或者直接转换成一个字符。

转换为十六进制字符串(最常用)

这通常用于日志、调试或网络数据传输中,因为字节本身可能不是可打印字符。

public class ByteToStringExample {
    public static void main(String[] args) {
        byte myByte = (byte) 0xA1; // 十六进制 A1,对应的十进制是 161
        // 方法一:使用 String.format
        String hexString1 = String.format("%02X", myByte);
        System.out.println("使用 String.format: " + hexString1); // 输出: A1
        // 方法二:使用 Integer 和 toString
        String hexString2 = Integer.toHexString(myByte & 0xFF); // 必须用 & 0xFF 处理负数
        System.out.println("使用 Integer.toHexString: " + hexString2.toUpperCase()); // 输出: A1
    }
}

注意byte 是有符号的,范围是 -128 到 127,当它作为整数处理时,会被符号扩展。(byte) 0xA1 实际上是 -95。& 0xFF 的作用是将 byte 转换为无符号的 int(0 到 255),这样 Integer.toHexString 才能得到正确的结果。

Java byte转string有哪些方法?-图2
(图片来源网络,侵删)

转换为字符(不推荐,除非你确定编码)

如果你想把 byte 当作某个编码(如 ISO-8859-1)下的一个字符来转换。

public class ByteToCharExample {
    public static void main(String[] args) {
        byte myByte = (byte) 0xE4; // 在 GBK 编码中,这可能是“中”字的一部分
        // 假设这个 byte 来自 ISO-8859-1 编码
        String charString = new String(new byte[]{myByte}, StandardCharsets.ISO_8859_1);
        System.out.println("作为 ISO-8859-1 字符: " + charString); // 输出: ä
        // 假设这个 byte 来自 GBK 编码
        try {
            String charStringGBK = new String(new byte[]{myByte}, "GBK");
            System.out.println("作为 GBK 字符: " + charStringGBK); // 输出: ä (因为只有一个字节,GBK 无法组成一个有效中文字符)
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}

单个 byte 转字符非常不可靠,几乎总是需要上下文(即它属于哪个编码的序列)。


byte[]String(最常见的情况)

这是最核心的转换,你需要明确指定编码。

指定编码(推荐做法)

这是最正确、最安全的方法。

Java byte转string有哪些方法?-图3
(图片来源网络,侵删)
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class ByteArrayToStringExample {
    public static void main(String[] args) {
        // "Hello" 字符串在 UTF-8 编码下的字节数组
        byte[] utf8Bytes = "Hello".getBytes(StandardCharsets.UTF_8);
        System.out.println("UTF-8 字节数组: " + Arrays.toString(utf8Bytes)); // [72, 101, 108, 108, 111]
        // "你好" 字符串在 UTF-8 编码下的字节数组
        byte[] gbkBytes = "你好".getBytes(StandardCharsets.UTF_8);
        System.out.println("UTF-8 字节数组: " + Arrays.toString(gbkBytes)); // [-28, -72, -83, -27, -107, -117]
        // --- 从 byte[] 转换回 String ---
        // 1. 使用 UTF-8 编码转换(推荐)
        String strFromUtf8 = new String(utf8Bytes, StandardCharsets.UTF_8);
        System.out.println("从 UTF-8 字节数组转换: " + strFromUtf8); // 输出: Hello
        String strFromUtf8Cn = new String(gbkBytes, StandardCharsets.UTF_8);
        System.out.println("从 UTF-8 字节数组转换: " + strFromUtf8Cn); // 输出: 你好
        // 2. 使用指定编码(如 GBK)
        // 假设我们有一个用 GBK 编码的字节数组
        byte[] gbkEncodedBytes = "你好".getBytes(java.nio.charset.StandardCharsets.GBK);
        System.out.println("GBK 字节数组: " + Arrays.toString(gbkEncodedBytes)); // [-60, -29, -70, -61]
        // 必须使用 GBK 编码才能正确转换回去
        String strFromGbk = new String(gbkEncodedBytes, "GBK");
        System.out.println("从 GBK 字节数组转换: " + strFromGbk); // 输出: 你好
        // 3. 错误示例:用错误的编码转换
        // 如果用 ISO-8859-1 去解码一个 UTF-8 的字节数组,会得到乱码
        String wrongString = new String(gbkBytes, StandardCharsets.ISO_8859_1);
        System.out.println("错误编码转换 (ISO-8859-1 解码 UTF-8): " + wrongString); // 输出: ä¸å¥½ (乱码)
    }
}

不指定编码(使用 JVM 默认编码)

这种方法不推荐,因为它会导致代码行为依赖于运行环境。

public class ByteArrayToStringDefaultExample {
    public static void main(String[] args) {
        byte[] bytes = "你好".getBytes(); // 使用 JVM 默认编码生成字节数组
        // 使用 JVM 默认编码转换回来
        String str = new String(bytes);
        System.out.println("使用默认编码转换: " + str);
        // 在中文 Windows 系统上(默认编码通常是 GBK),这可能是正确的。
        // 但在 Linux 或 macOS 上(默认编码通常是 UTF-8),这可能会乱码。
    }
}

Stringbyte[]

这是上述过程的逆操作,同样需要指定编码。

import java.nio.charset.StandardCharsets;
public class StringToByteArrayExample {
    public static void main(String[] args) {
        String str = "Hello, 世界!";
        // 1. 使用 UTF-8 编码
        byte[] utf8Bytes = str.getBytes(StandardCharsets.UTF_8);
        System.out.println("UTF-8 编码的字节数组长度: " + utf8Bytes.length); // 输出: 13 (H,e,l,l,o,,, ,世,界,!)
        System.out.println("内容: " + Arrays.toString(utf8Bytes));
        // 2. 使用 GBK 编码
        byte[] gbkBytes = str.getBytes(java.nio.charset.StandardCharsets.GBK);
        System.out.println("GBK 编码的字节数组长度: " + gbkBytes.length); // 输出: 12 (世,界 在 GBK 中占 2 字节)
        System.out.println("内容: " + Arrays.toString(gbkBytes));
        // 3. 使用默认编码(不推荐)
        byte[] defaultBytes = str.getBytes();
        System.out.println("默认编码的字节数组长度: " + defaultBytes.length);
    }
}

  1. 明确编码:在处理 byte[]String 之间的转换时,始终要明确知道并指定所使用的字符编码。
  2. 优先使用 UTF-8:除非有特殊的历史遗留系统限制,否则请始终使用 UTF-8 作为你的应用编码标准。
  3. 使用 StandardCharsets:Java 7 引入了 java.nio.charset.StandardCharsets 类,它为标准编码提供了常量(如 StandardCharsets.UTF_8),使用它比直接使用字符串字面量(如 "UTF-8")更安全,因为它可以在编译时检查编码名称是否有效,避免了 UnsupportedEncodingException
  4. 避免使用默认编码:不要调用 new String(byte[])String.getBytes() 不带参数的重载方法,因为它们依赖于 JVM 的默认设置,这会使你的代码不可移植。
  5. 处理单个字节:如果目标是得到字节的十六进制表示,请使用 String.format("%02X", myByte & 0xFF)Integer.toHexString(myByte & 0xFF),不要尝试直接将其转换为字符,除非你 100% 确定其编码上下文。
分享:
扫描分享到社交APP
上一篇
下一篇