gpt4 book ai didi

java - 具有旧语义的 Invokespecial : call instance method of other class

转载 作者:行者123 更新时间:2023-12-01 19:44:48 26 4
gpt4 key购买 nike

根据this在旧的java版本中,有一个限制较少的invokespecial版本,称为invokenonvirtual。该指令将允许您调用实例方法而无需虚拟查找,如果我没猜错的话,这些方法可能属于当前类的不可分配类。使用invokespecial,这种情况发生了变化,因为它仅用于调用 super 方法、私有(private)方法或初始化方法。

我的问题是:java 8(或更高版本)有没有办法绕过这些结构限制 [4.9.2]的invokespecial指令并在没有虚拟查找的情况下调用不同类的方法(即与当前类不兼容赋值的类)

我可以使用 no-verify 标志来禁用验证过程,但是有更优雅的方法吗?

最佳答案

您正在混淆两个不同的问题。 invokenonvirtualinokespecial 是相同的,并且一直如此。它们只是同一操作码的两个不同名称。

您链接的问题正在谈论一个单独的功能ACC_SUPER,它有自己漫长而复杂的历史。

基本上,在 Java 的早期版本中, super 调用的编译被破坏了。编译父类(super class)调用时,它会在编译时将 invokespecial 插入父类(super class)方法。如果稍后更改类层次结构,即使在层次结构的中间点插入新的重写,它仍会尝试调用它被编译要调用的方法。

请注意,这仍然不允许您调用不相关的类中的方法 - 该问题仅与编译后在同一继承更改中添加的同一方法的不同重写有关。

Java 作者意识到他们的错误后,他们更新了 JVM 对 invokespecial 的处理,以正确处理 super 调用。现在,无论指令中指定哪个方法,它都会在链接/运行时遍历父类(super class)层次结构并调用适当的方法。

但是,他们担心在旧版本 Java 下编译的代码依赖于损坏的行为,因此为了向后兼容,他们添加了一个新的类文件标志 ACC_SUPER。如果在类上设置了该标志,则它具有新的(正确的)行为,如果没有,则它使用旧的行为。由于旧的类文件是在该标志存在之前编译的,因此它们不会设置它。同时,编译器已更新为在所有新类上设置 ACC_SUPER ,每个人都很高兴...

截至 2011 年。事实证明,java.lang.Thread 有一个用户不应调用的安全敏感方法。为了防止人们从 Thread 的子类调用它,他们重写了它以引发异常。然而,someone realized黑客可以在没有 ACC_SUPER 标志的情况下定义 Thread 的子类,从而跳过安全检查并调用该方法的危险版本并突破 Java 沙箱。

不幸的是,修复此安全漏洞的唯一方法是完全删除 ACC_SUPER 功能 - 也就是说,将每个类视为设置了标志,无论实际上是否设置了该标志。它在 Java 7 update 13 中被匆忙修复,而在 Java 8 中,规范本身已更改为记录 ACC_SUPER 不再产生任何效果。

所以答案是否定的,在 7u13 之后的任何 Java 版本中,或者实现安全修复的任何更新中,都没有办法获得 super 调用的旧行为。

关于java - 具有旧语义的 Invokespecial : call instance method of other class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53807175/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com