【问题标题】:Java: Does type-casting cause an operation during run-time?Java:类型转换是否会在运行时导致操作?
【发布时间】:2018-12-19 10:21:20
【问题描述】:

JLS 声明

从 S 类型到 T 类型的特定转换允许在编译时将 S 类型的表达式视为具有 T 类型。 在某些情况下,这将需要在运行时执行相应的操作来检查转换的有效性或将表达式的运行时值转换为适合新类型 T 的形式。

The list of JVM instructions 包含

checkcast

操作

检查对象是否属于给定类型

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 需要多少性能?

【问题讨论】:

    标签: java casting type-conversion


    【解决方案1】:

    当然,确切的细节确实取决于架构。

    基元和对象的铸造在很大程度上是不相关的。

    对于原始转换,可能需要在整数和浮点寄存器之间移动值或进行符号扩展,但这些通常是非常快的操作,与内存访问时间相比相形见绌。

    对象不同。

    bytecode->native 编译器或许能够证明一个对象的转换总是成功的,所以在运行时不会发生任何动作。

    通常情况下,成功的checkcast 几乎没有性能开销。有各种优化(在某处可能有合理的指南)。即使您只是想有效地调用虚拟方法,大多数优化也是必要的。此外,泛型只是“编译器虚构”,因此隐式强制转换非常常见。在过去,抽象类可能比接口更受青睐,因为它更简单的虚拟方法分派,但二十年来没有人关心过。

    在您的示例代码中,转换可能显示为始终成功。否则,由于String 是最终的,唯一需要检查的是对象头中的类型信息是否正确。不需要进一步的内存访问。

    【讨论】:

    • 几乎满足我的要求。但是你写的优化是什么?你的意思是优化checkcast的必要性吗?为什么抽象类比接口具有更简单的虚拟方法调度?提前谢谢你。
    • @user10385242 类只有单一继承。这意味着您可以从基类开始编号方法。然后,找到方法地址只需将固定偏移量加载到每个对象头都有一个指针的类数据结构中。接口更复杂。我对通常所做的优化没有很好的参考。例如,HotSpot 已经能够内联虚拟方法的两种不同可能实现(最初用于 NIO 缓冲区)。
    • 所以如果我理解正确的话,抽象类,因为java只有单继承,所以可以给方法编号固定偏移量,这个偏移量保留在每个继承自它的类中。然后,这允许任何派生类通过将相同的偏移量加载到类数据结构中来找到相同的确切方法。如果此方法是强制转换的唯一目标,则内联不同的方法实现将允许跳过检查强制转换。对吗?
    • @stackoverflow.com/users/4725/tom-hawtin-tackline 关于注释格式的说明似乎不起作用,嗯...也许可以
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    • 2020-09-29
    • 1970-01-01
    相关资源
    最近更新 更多