Java数组类型一致性是编译期强制规则:基本类型数组仅接受严格匹配字面量,引用类型数组允许子类和null;静态与动态初始化均受编译检查,拷贝操作中System.arraycopy和Arrays.copyOf在运行时校验,clone()仅保证数组类型一致。

Java 数组要求所有元素在编译期就满足类型一致性,这不是运行时约束,而是编译器强制执行的硬性规则。一旦声明为某种类型,每个初始化值或赋值目标都必须严格匹配该类型,或能被其接受(如自动拓宽、子类实例、null 等),否则直接报错,根本不会生成字节码。
基本类型数组只认“本家”字面量
int[] 只接受整数字面量(如 1、-5),不接受 2L(long)或 3.0f(float),哪怕它们数值上可转换——因为数组初始化阶段不触发隐式拓宽转换。只有显式转换才合法:
-
错误写法:
int[] a = {1, 2L, 3.0f}; -
正确写法:
int[] a = {1, (int)2L, (int)3.0f};或{1, 2, 3};
引用类型数组允许子类与 null
String[] 可以存 "hello"、null,但不能存 new Object();而 Object[] 则能容纳任意对象,包括 String、Integer 和 null:
-
合法:
Object[] obj = {"a", new Integer(42), null}; -
非法:
String[] s = {new Object()};—— 编译失败
静态初始化和动态初始化都走编译检查
两种写法都会触发类型校验,只是时机略有不同:
立即学习“Java免费学习笔记(深入)”;
-
花括号初始化(如
double[] d = {1, 2.5}):编译器逐个解析字面量,任一不匹配即报错 -
new + 单独赋值(如
int[] a = new int[2]; a[0] = "x";):错误出现在a[0] = "x"这一行,因字符串无法赋给 int 变量
拷贝过程中的类型检查是另一层逻辑
数组拷贝不改变类型一致性原则,但不同方式校验位置不同:
-
System.arraycopy:运行时检查,源与目标类型不兼容(如 int[] → String[])会抛ArrayStoreException -
Arrays.copyOf:先编译期确认入参类型,再复用arraycopy的运行时校验 -
clone():只保证返回数组类型与原数组一致,不验证元素内容是否合规


















