java - Java:类型转换是否会在运行时导致操作?
问题描述
JLS 指出
从 S 类型到 T 类型的特定转换允许在编译时将 S 类型的表达式视为具有 T 类型。在某些情况下,这将需要在运行时执行相应的操作来检查转换的有效性或将表达式的运行时值转换为适合新类型 T 的形式。
JVM指令列表包含
检查广播
手术
检查对象是否属于给定类型
Object o = new String();
String s =
(String)//what does the JVM do?
o;
由于描述指出 checkcast 在失败时抛出ClassCastException并检查是否可以将objectref强制转换为给定类型,我猜想如果我在代码中向下转换,这可能是在运行时执行的指令。
首先{1}:这个假设正确吗?
如果是这样:
Object o = (Object)//What do I do now?
new String();
{2} 这也是隐式或显式向上转换的情况吗?
{3} 这条指令在其他微优化的规模上会产生多少运行时损失?
例如,与将包含对象引用的字段移动到局部函数变量以加快访问时间或其他类型的微优化相比,checkcast 需要多少性能?
解决方案
当然,确切的细节确实取决于架构。
基元和对象的转换在很大程度上是不相关的。
对于原始转换,可能需要在整数和浮点寄存器之间移动值或符号扩展,但这些通常是非常快的操作,与内存访问时间相比相形见绌。
对象不同。
bytecode->native 编译器可能能够证明对象的转换总是成功的,因此在运行时不会发生任何动作。
通常,成功的checkcast
. 有各种优化(在某处可能有合理的指南)。即使您只是想有效地调用虚拟方法,大多数优化也是必要的。此外,泛型只是“编译器虚构”,因此隐式强制转换非常常见。在过去,抽象类可能比接口更受欢迎,因为它更简单的虚拟方法分派,但二十年来没有人关心过。
在您的示例代码中,转换可能显示为始终成功。否则,与String
最终一样,唯一需要检查的是对象头中的类型信息是否正确。不需要进一步的内存访问。
推荐阅读
- mysql - mysq:在 FROM 和 WHERE 子句中使用相同的子查询而不重复?
- ios - “将所有 32 位浮点操作作为 64 位浮点执行”与 .net 是否兼容更多或更少?
- javascript - 星系模拟:更改点的颜色并在鼠标悬停时显示文本
- text - 这是什么奇怪的角色?
- nginx - 如何在 Kubernetes 上访问简单的 nginx 部署?
- vhdl - vhdl 进程中的顺序语句是如何合成的?
- javascript - 使用 html js 或 reactjs 框架自动读取本地文件
- java - 有没有办法只使recyclerview中的项目透明?
- php - 两个字段等于一个的 SQL JOIN 语句 [CodeIgniter]
- strapi - Strapi 中的完整媒体 URL