Java 语言中不可用的字节码功能
目前 (Java 6) 是否有一些您可以在 Java 字节码中执行而您无法在 Java 语言中执行的操作?
Are there currently (Java 6) things you can do in Java bytecode that you can't do from within the Java language?
我知道两者都是图灵完备的,所以将可以做到"理解为可以做得更快/更好,或者只是以不同的方式".
I know both are Turing complete, so read "can do" as "can do significantly faster/better, or just in a different way".
我正在考虑像 invokedynamic
这样的额外字节码,它不能使用 Java 生成,除非特定的字节码用于未来版本.
I'm thinking of extra bytecodes like invokedynamic
, which can't be generated using Java, except that specific one is for a future version.
推荐答案
据我所知,Java 6 支持的字节码中没有主要功能无法从 Java 源代码中访问.主要原因显然是 Java 字节码在设计时考虑了 Java 语言.
As far as I know there are no major features in the bytecodes supported by Java 6 that are not also accessible from Java source code. The main reason for this is obviously that the Java bytecode was designed with the Java language in mind.
但是,有些功能不是由现代 Java 编译器产生的:
There are some features that are not produced by modern Java compilers, however:
ACC_SUPER
标志:
这是一个可以在类上设置的标志,并指定如何为该类处理 invokespecial
字节码的特定极端情况.它是由所有现代 Java 编译器设置的(如果我没记错的话,现代"是 >= Java 1.1)并且只有古代 Java 编译器才会生成未设置的类文件.此标志仅出于向后兼容的原因而存在.请注意,从 Java 7u51 开始,出于安全原因,ACC_SUPER 将被完全忽略.
This is a flag that can be set on a class and specifies how a specific corner case of the invokespecial
bytecode is handled for this class. It is set by all modern Java compilers (where "modern" is >= Java 1.1, if I remember correctly) and only ancient Java compilers produced class files where this was un-set. This flag exists only for backwards-compatibility reasons. Note that starting with Java 7u51, ACC_SUPER is ignored completely due to security reasons.
jsr
/ret
字节码.
这些字节码用于实现子例程(主要用于实现 finally
块).它们自 Java 6 起不再生产.不推荐使用它们的原因是它们使静态验证复杂化了很多而没有很大的收益(即使用的代码几乎总是可以通过正常跳转重新实现而开销很小).
These bytecodes were used to implement sub-routines (mostly for implementing finally
blocks). They are no longer produced since Java 6. The reason for their deprecation is that they complicate static verification a lot for no great gain (i.e. code that uses can almost always be re-implemented with normal jumps with very little overhead).
在一个类中有两个方法,只是返回类型不同.
Having two methods in a class that only differ in return type.
Java 语言规范不允许同一类中的两个方法仅返回类型不同(即,相同的名称、相同的参数列表,...).然而,JVM 规范没有这样的限制,所以一个类文件可以包含两个这样的方法,只是没有办法使用普通的 Java 编译器生成这样一个类文件.这个答案中有一个很好的例子/解释.
The Java language specification does not allow two methods in the same class when they differ only in their return type (i.e. same name, same argument list, ...). The JVM specification however, has no such restriction, so a class file can contain two such methods, there's just no way to produce such a class file using the normal Java compiler. There's a nice example/explanation in this answer.
相关文章