Java类型转换分基本类型和引用类型:基本类型靠字节码指令(如i2l)直接位操作;引用类型向上转型无指令,向下转型用checkcast运行时检查;泛型因类型擦除无运行时转换;JNI调用不经过JVM转换。

Java 中的类型转换分为基本类型转换和引用类型转换,它们的底层机制完全不同。JVM 并不统一处理所有“转换”,而是依据语义在编译期和运行时分层实现。
基本类型转换靠字节码指令直接操作数值
JVM 提供了明确的类型转换指令(如 i2l、l2f、f2d 等),每条指令对应一种源类型到目标类型的二进制位宽调整或格式重解释。
- 编译器根据上下文判断是否需要插入转换指令。例如
int a = 10; long b = a;,javac 会生成iload_0+i2l+lstore_1。 - 这些指令不查表、不调用函数,由 JVM 执行引擎直接完成寄存器/栈中数据的位复制与截断/扩展。
- 整数扩展(如
i2l)高位补符号位;浮点转整数(如f2i)会向零截断,并可能因溢出返回0x80000000或0x7fffffff。
引用类型转换本质是运行时类型检查
向上转型(如 Object o = new String())无需指令,编译期已确认安全,字节码中不体现。
向下转型(如 (String) o)则必须通过 checkcast 指令执行:
- JVM 在运行时检查对象的实际类是否是目标类型的子类或实现类;
- 检查过程基于类元数据中的继承关系链(方法区中已加载的类结构);
- 若失败,立即抛出
ClassCastException,不进行任何内存拷贝或重构。
泛型类型在运行时不存在转换行为
因为 Java 泛型采用类型擦除,List<String> 和 List<Integer> 编译后都是 List,字节码中无泛型信息。
-
get()方法返回Object,实际使用时需手动强转(如(String) list.get(0)),该强转属于引用类型向下转型,走checkcast; - 编译器插入的桥接方法(bridge method)只为维持多态语义,不参与类型转换逻辑。
JNI 层的类型传递不经过 JVM 转换
Java 调用 native 方法时,int 参数以 32 位整数二进制形式直接传入 C 函数的 jint 形参。
-
jint在jni.h中定义为int32_t,C 编译器静态绑定; - JVM 不做任何类型解析或转换,只按 ABI 规则压栈或传寄存器;
- 返回值同理,native 函数返回
jint,JVM 直接当作 Javaint接收。
不复杂但容易忽略

















