声明并初始化赋值
这是最直接的方式,在创建数组的同时就为其分配内存并赋值。
使用 new 关键字和初始值列表
这是最常见的方式,代码清晰易读。
// 1. 声明一个 byte 数组变量
byte[] byteArray1;
// 2. 使用 new 创建数组并指定长度,同时初始化
byteArray1 = new byte[]{10, 20, 30, 40, 50};
// 也可以在声明的同时完成初始化
byte[] byteArray2 = new byte[]{1, 2, 3, 4};
// 使用 var 关键字 (Java 10+)
var byteArray3 = new byte[]{100, -50, 0};
简化的初始化语法 (推荐)
如果不需要显式使用 new 关键字,可以使用更简洁的语法。
// 这是最推荐的写法,简洁明了
byte[] byteArray4 = {10, 20, 30, 40, 50};
// 使用 var 关键字 (Java 10+)
var byteArray5 = {-1, 0, 1, 2};
注意:这种方式会自动计算数组长度,无需手动指定。
先声明,后赋值
我们需要先声明数组,稍后再为其分配内存和赋值。
指定长度,再逐个赋值
这种方式适用于先确定数组大小,但初始值是动态计算或来自其他数据源的情况。
// 1. 声明数组,并指定其长度为 5 byte[] byteArray6 = new byte[5]; // 2. 通过索引逐个赋值 // 数组索引从 0 开始 byteArray6[0] = 1; byteArray6[1] = 2; byteArray6[2] = 3; byteArray6[3] = 4; byteArray6[4] = 5; // 访问数组元素 System.out.println(byteArray6[0]); // 输出: 1
使用循环赋值
当需要根据某种规律(例如递增、递减)为所有元素赋值时,循环是最佳选择。
// 创建一个长度为 10 的 byte 数组
byte[] byteArray7 = new byte[10];
// 使用 for 循环赋值
for (int i = 0; i < byteArray7.length; i++) {
// 将每个元素赋值为它的索引值
byteArray7[i] = (byte) i; // 注意这里的类型转换
}
// 使用增强 for 循环 (for-each) 来遍历和打印
System.out.println("byteArray7 内容:");
for (byte b : byteArray7) {
System.out.print(b + " "); // 输出: 0 1 2 3 4 5 6 7 8 9
}
为什么需要 (byte) i?
因为 i 是 int 类型,而 byte 数组的元素必须是 byte 类型,虽然 i 的值在 0 到 9 之间,完全在 byte 的范围内(-128 到 127),但 Java 编译器仍然要求你进行显式类型转换,以确保类型安全。
从其他来源赋值
在实际开发中,我们常常需要从字符串、文件、网络等来源获取数据并填充到 byte 数组中。
从 String 转换
可以使用 String.getBytes() 方法将字符串转换为 byte 数组。
String str = "Hello, Java!";
byte[] byteArray8 = str.getBytes(); // 使用平台默认的字符编码
// 指定编码(推荐,避免平台不一致问题)
try {
byte[] byteArray9 = str.getBytes("UTF-8");
System.out.println(new String(byteArray9, "UTF-8")); // 输出: Hello, Java!
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
从 ByteBuffer 赋值
java.nio.ByteBuffer 是处理字节数据的强大工具,尤其是在进行 I/O 操作时。
import java.nio.ByteBuffer; // 创建一个 ByteBuffer,并放入一些数据 ByteBuffer buffer = ByteBuffer.allocate(4); buffer.put((byte) 10); buffer.put((byte) 20); buffer.put((byte) 30); buffer.put((byte) 40); // 准备读取数据 buffer.flip(); // 将 limit 设置为 position,position 设置为 0 // 将 ByteBuffer 的内容获取到 byte 数组 byte[] byteArray10 = new byte[buffer.remaining()]; // remaining() 是剩余可读字节数 buffer.get(byteArray10); // 打印结果 System.out.println(java.util.Arrays.toString(byteArray10)); // 输出: [10, 20, 30, 40]
从文件读取
使用 FileInputStream 从文件中读取数据到 byte 数组。
import java.io.FileInputStream;
import java.io.IOException;
try (FileInputStream fis = new FileInputStream("example.txt")) {
// 先获取文件大小
byte[] byteArray11 = new byte[fis.available()];
// 读取文件内容到数组
fis.read(byteArray11);
System.out.println("从文件读取的字节数组长度: " + byteArray11.length);
} catch (IOException e) {
e.printStackTrace();
}
数组拷贝赋值
当你想复制一个已有的 byte 数组到另一个新数组时。
System.arraycopy() (最高效)
这是性能最高的数组拷贝方法,是本地方法实现。
byte[] sourceArray = {1, 2, 3, 4, 5};
byte[] destinationArray = new byte[sourceArray.length];
// 参数: 源数组, 源起始位置, 目标数组, 目标起始位置, 拷贝长度
System.arraycopy(sourceArray, 0, destinationArray, 0, sourceArray.length);
System.out.println(java.util.Arrays.toString(destinationArray)); // 输出: [1, 2, 3, 4, 5]
Arrays.copyOf() (最方便)
java.util.Arrays.copyOf() 方法更加简洁,可以指定新数组的长度。
import java.util.Arrays;
byte[] sourceArray2 = {10, 20, 30};
// 拷贝整个数组,新数组长度与源数组相同
byte[] destinationArray2 = Arrays.copyOf(sourceArray2, sourceArray2.length);
System.out.println(java.util.Arrays.toString(destinationArray2)); // 输出: [10, 20, 30]
// 拷贝部分数组,并指定新长度
byte[] destinationArray3 = Arrays.copyOf(sourceArray2, 3); // 拷贝前3个元素
byte[] destinationArray4 = Arrays.copyOf(sourceArray2, 5); // 拷贝所有元素,不足部分用 0 填充
System.out.println(java.util.Arrays.toString(destinationArray3)); // 输出: [10, 20, 30]
System.out.println(java.util.Arrays.toString(destinationArray4)); // 输出: [10, 20, 30, 0, 0]
| 场景 | 推荐方法 | 示例 |
|---|---|---|
| 声明并初始化 | 简化初始化语法 | byte[] arr = {1, 2, 3}; |
| 动态赋值 | 循环 + 索引 | for (int i=0; i<arr.length; i++) { arr[i] = ...; } |
| 从字符串转换 | String.getBytes() |
byte[] arr = "abc".getBytes("UTF-8"); |
| 从文件/IO流 | FileInputStream.read() |
fis.read(arr); |
| 复制数组 | System.arraycopy() (高效) 或 Arrays.copyOf() (方便) |
System.arraycopy(src, 0, dest, 0, len); |
选择哪种赋值方式完全取决于你的具体需求,例如代码的可读性、性能要求以及数据来源等,对于简单的静态数据,推荐使用简化语法;对于动态数据,循环和 I/O 方法是常用选择。
