什么Java编译器使用jsr指令,为什么?

什么Java编译器使用jsr指令,为什么?,java,bytecode,Java,Bytecode,Java字节码语言具有JSR指令 我用Java7编译器编译的代码中没有一个使用此指令 然而,有时我下载的Java二进制文件确实使用它,尽管很少使用 我想知道哪些编译器使用该指令,以及哪些Java代码构造会导致他们使用该指令 编辑这不是重复的,因为它指的是JSR字节码指令,而不是Java规范请求,根据: 在Oracle为Java SE 6之前的Java编程语言实现编译器时,jsr指令与ret指令一起用于finally子句的实现 实际上,在Java7类文件中甚至不允许使用JSR指令。它只允许在49.

Java字节码语言具有JSR指令

我用Java7编译器编译的代码中没有一个使用此指令

然而,有时我下载的Java二进制文件确实使用它,尽管很少使用

我想知道哪些编译器使用该指令,以及哪些Java代码构造会导致他们使用该指令

编辑这不是重复的,因为它指的是JSR字节码指令,而不是Java规范请求

,根据:

在Oracle为Java SE 6之前的Java编程语言实现编译器时,
jsr
指令与
ret
指令一起用于finally子句的实现


实际上,在Java7类文件中甚至不允许使用JSR指令。它只允许在49.0或更早版本的类文件中使用,对应于Java 5或更早版本。实际上,它早在那之前就不再使用了

JSR/RET机制最初用于实现finally块。然而,他们认为节省的代码大小不值得额外的复杂性,因此逐渐被淘汰

我不知道确切的版本,因为我找不到任何那么旧的编译器,但根据我在网上找到的讨论,这种转换似乎发生在Java1.2-1.3时代,不同的编译器在不同的时间切换。我从未从这些旧编译器中看到过合法的类文件,但您永远不知道它何时会发生


实际上,我在野外看到的JSR的唯一用途是模糊处理。例如,Zelix Klassmaster曾将其用于字符串解密代码。我也在我自己的几个Java crackmes中使用过它。

这与搜索负责字节码生成的OpenJDK源代码是一致的:它出现在
try
块的字节码生成中,其中最后出现了
,它是为实现
finally
机制而设计的(允许从方法中的多个位置“调用”相同的代码段),但在
javac
的更高版本中基本上被消除了,在后者中,编译器只需内联复制代码即可完成任务。也可能被其他一些针对JVM的语言使用。这些是哪些二进制文件?我认为Java7必须停止使用
jsr
,因为它与该版本引入的“堆栈映射”内部结构相冲突。但是
javac
的早期版本已经不再使用
jsr
。如果遇到
jsr
,很可能是在Java 7之前创建的.class中,很可能是在之前的几个版本中。密切相关:当我在IBM AS/400类文件验证器上工作时,我讨厌使用
jsr
进行模糊处理的代码,因为它的验证变得非常复杂(而且速度慢且占用存储空间)。(使用从模糊代码中窃取的技术,我编写了BigUglyMethod,一个类文件,它通过将Sun的验证器打结而破坏了它。但是我们的,当然是以出色的方式处理的。)@Hot-Licks-Yeah验证很烦人。我不得不多次阅读热点源代码,以了解JSR是如何被验证的,因为规范非常模糊。好的一面是,我在验证器中还发现了各种很酷的未记录的把戏。例如,我构造了一个方法,该方法可以很好地验证if语句,但只是重新排列if语句的分支,这会由于验证程序代码的三个不同部分之间的微妙交互而导致验证失败。@paj28:
jsr
如果只能调用声明的“子例程”,会不会造成这样的困难,每个只能在开始时输入,只能从另一个子例程调用,并且只能通过
ret
或突然完成(返回或抛出)退出?在
finally
块中复制代码看起来非常难看,特别是因为与
finally
相关的清理通常会调用嵌套的
try
块。@supercat,大多数情况已经是这样了。子例程只能从开始输入,只能从一个位置返回,并且只能从单个子例程中调用。复杂性来自这样一个事实,即您必须为局部变量维护一堆脏位,并且在返回时,您必须执行三向合并。
。。。他们认为节省的代码大小不值得付出额外的复杂性,它逐渐被淘汰了
我知道这个问题很老了,但我在其他地方找不到这种变化的参考。这项决定是否有文件记录?