简单的数组复制(最常见)
这是最基础的需求,你想创建一个新的 byte 数组,其内容与原数组完全相同,这在 Java 中有几种高效的方法。

方法1: System.arraycopy() - 性能最优
这是最推荐的方法,因为它是一个本地方法,性能非常高,专门用于数组之间的复制。
public class ByteArrayCopy {
public static void main(String[] args) {
byte[] originalArray = {1, 2, 3, 4, 5};
// 创建一个与原数组长度相同的新数组
byte[] copiedArray = new byte[originalArray.length];
// 使用 System.arraycopy 进行复制
// 参数: 源数组, 源数组起始位置, 目标数组, 目标数组起始位置, 复制长度
System.arraycopy(originalArray, 0, copiedArray, 0, originalArray.length);
// 验证结果
System.out.println("Original: " + Arrays.toString(originalArray));
System.out.println("Copied: " + Arrays.toString(copiedArray));
// 修改原数组,不影响新数组
originalArray[0] = 99;
System.out.println("--- After modifying original ---");
System.out.println("Original: " + Arrays.toString(originalArray));
System.out.println("Copied: " + Arrays.toString(copiedArray)); // 值未改变
}
}
优点:
- 性能最高:由 JVM 直接优化,速度最快。
- 灵活性高:可以指定源数组和目标数组的起始位置以及复制的长度。
方法2: Arrays.copyOf() - 更简洁
java.util.Arrays.copyOf() 方法提供了更简洁的语法,内部也是调用 System.arraycopy() 实现的。
import java.util.Arrays;
public class ByteArrayCopyWithArrays {
public static void main(String[] args) {
byte[] originalArray = {1, 2, 3, 4, 5};
// 使用 Arrays.copyOf 复制整个数组
byte[] copiedArray = Arrays.copyOf(originalArray, originalArray.length);
System.out.println("Original: " + Arrays.toString(originalArray));
System.out.println("Copied: " + Arrays.toString(copiedArray));
}
}
优点:

- 代码简洁:一行代码即可完成。
- 灵活性:可以轻松复制数组的部分内容(
Arrays.copyOf(originalArray, 3)会复制前3个元素)。
方法3: 克隆 (clone()) - 对象级别的复制
每个数组对象都有一个 clone() 方法,它会创建一个新数组,并将原数组的元素复制到新数组中。
public class ByteArrayClone {
public static void main(String[] args) {
byte[] originalArray = {1, 2, 3, 4, 5};
// 使用 clone() 方法
byte[] clonedArray = originalArray.clone();
System.out.println("Original: " + Arrays.toString(originalArray));
System.out.println("Cloned: " + Arrays.toString(clonedArray));
}
}
优点:
- 语法简单:直接在数组对象上调用。
缺点:
- 灵活性差:只能复制整个数组,无法指定范围。
- 可读性:相比
Arrays.copyOf,clone()的意图可能不够明确。
带数据转换的复制
当“转换”不仅仅是复制,而是对数据进行某种处理时,就需要手动遍历和转换。

示例:将每个字节的值乘以2
import java.util.Arrays;
public class ByteArrayTransform {
public static void main(String[] args) {
byte[] originalArray = {1, 2, 3, 4, 5};
byte[] transformedArray = new byte[originalArray.length];
for (int i = 0; i < originalArray.length; i++) {
// 注意:这里直接相乘可能会溢出,但 byte 会自动回绕
transformedArray[i] = (byte) (originalArray[i] * 2);
}
System.out.println("Original: " + Arrays.toString(originalArray));
System.out.println("Transformed: " + Arrays.toString(transformedArray)); // [2, 4, 6, 8, 10]
}
}
在这个场景下,我们创建了一个新数组,并通过循环将原数组中的每个元素处理后放入新数组。
处理不同编码的字符串转换
这是非常常见的需求,比如将一个 GBK 编码的 byte 数组转换成 UTF-8 编码的 byte 数组。
核心思想:
- 将源 byte 数组用其原始编码解码成
String。 - 将这个
String用目标编码重新编码成新的 byte 数组。
示例:GBK 转 UTF-8
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class ByteArrayEncodingConversion {
public static void main(String[] args) {
String originalString = "你好,世界"; // 包含中文字符
// 1. 将字符串按 GBK 编码成 byte 数组
byte[] gbkBytes = originalString.getBytes(Charset.forName("GBK"));
System.out.println("GBK Bytes: " + Arrays.toString(gbkBytes));
// 2. 将 GBK 的 byte 数组按 GBK 解码回 String
String fromGbkString = new String(gbkBytes, Charset.forName("GBK"));
System.out.println("Decoded from GBK: " + fromGbkString);
// 3. 将这个 String 按 UTF-8 编码成新的 byte 数组
byte[] utf8Bytes = fromGbkString.getBytes(StandardCharsets.UTF_8);
System.out.println("UTF-8 Bytes: " + Arrays.toString(utf8Bytes));
// 验证一下长度变化,GBK 对中文通常用2个字节,UTF-8 用3个
System.out.println("GBK Bytes Length: " + gbkBytes.length);
System.out.println("UTF-8 Bytes Length: " + utf8Bytes.length);
}
}
注意:
- 如果编码和解码的字符集不一致,很可能会导致乱码,从而得到错误的新 byte 数组。
加密/解密转换
在密码学领域,byte 数组之间的转换是核心操作,使用 AES 算法加密一个 byte 数组。
这通常需要使用第三方库,如 Bouncy Castle 或 Java 内置的 javax.crypto 包。
示例:使用 AES 加密(概念性代码)
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Arrays;
import java.util.Base64;
public class ByteArrayEncryption {
// 注意:实际项目中密钥管理要非常小心,这里仅作演示
private static final String AES_KEY = "ThisIsASecretKey123"; // 16, 24, or 32 bytes for AES-128, AES-192, AES-256
public static byte[] encrypt(byte[] originalBytes) throws Exception {
// 1. 生成密钥
SecretKeySpec secretKey = new SecretKeySpec(AES_KEY.getBytes(StandardCharsets.UTF_8), "AES");
// 2. 创建 Cipher 实例
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
// 3. 执行加密,得到加密后的 byte 数组
byte[] encryptedBytes = cipher.doFinal(originalBytes);
return encryptedBytes;
}
public static void main(String[] args) throws Exception {
String originalString = "This is a secret message.";
byte[] originalBytes = originalString.getBytes(StandardCharsets.UTF_8);
System.out.println("Original Bytes: " + Arrays.toString(originalBytes));
// 转换:原始 byte 数组 -> 加密后的 byte 数组
byte[] encryptedBytes = encrypt(originalBytes);
// Base64 编码方便打印,否则很多字节是不可见字符
System.out.println("Encrypted Bytes (Base64): " + Base64.getEncoder().encodeToString(encryptedBytes));
}
}
在这个例子中,encrypt 方法就是一个典型的“byte数组转byte数组”的转换,但它执行的是复杂的加密算法。
总结与最佳实践
| 场景 | 推荐方法 | 说明 |
|---|---|---|
| 简单复制 | System.arraycopy() |
性能最佳,适合性能敏感代码。 |
Arrays.copyOf() |
代码最简洁,推荐在大多数业务代码中使用。 | |
clone() |
语法简单,但灵活性差,可读性略逊。 | |
| 数据转换 | for 循环 |
需要对每个元素进行逻辑处理时,手动遍历是唯一选择。 |
| 编码转换 | String 作为桥梁 |
new String(bytes, charset) 解码,str.getBytes(newCharset) 编码。 |
| 加密/解密 | 专业加密库 (如 Bouncy Castle) | 使用 Cipher 等类,遵循安全编码规范。 |
核心要点:
- 明确你的“转换”意图:你只是想复制一份,还是想对数据进行修改、编码或加密?
- 根据意图选择工具:
- 复制 ->
Arrays.copyOf(首选) 或System.arraycopy(性能优先)。 - 处理 ->
for循环。 - 编码 ->
String类的getBytes()和构造函数。 - 加密 ->
javax.crypto或 Bouncy Castle。
- 复制 ->
希望这个详细的解释能帮助你更好地理解和处理 Java 中的 byte 数组转换问题!
