Bytecode features not available in the Java language

后端 未结 9 1380
北恋
北恋 2020-12-04 04:28

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\"

相关标签:
9条回答
  • 2020-12-04 04:53
    • GOTO can be used with labels to create your own control structures (other than for while etc)
    • You can override the this local variable inside a method
    • Combining both of these you can create create tail call optimised bytecode (I do this in JCompilo)

    As a related point you can get parameter name for methods if compiled with debug (Paranamer does this by reading the bytecode

    0 讨论(0)
  • 2020-12-04 04:55

    I wrote a bytecode optimizer when I was a I-Play, (it was designed to reduce the code size for J2ME applications). One feature I added was the ability to use inline bytecode (similar to inline assembly language in C++). I managed to reduce the size of a function that was part of a library method by using the DUP instruction, since I need the value twice. I also had zero byte instructions (if you are calling a method that takes a char and you want to pass an int, that you know does not need to be cast I added int2char(var) to replace char(var) and it would remove the i2c instruction to reduce the size of the code. I also made it do float a = 2.3; float b = 3.4; float c = a + b; and that would be converted to fixed point (faster, and also some J2ME did not support floating point).

    0 讨论(0)
  • 2020-12-04 05:01

    Maybe section 7A in this document is of interest, although it's about bytecode pitfalls rather than bytecode features.

    0 讨论(0)
  • 2020-12-04 05:03

    In Java language the first statement in a constructor must be a call to the super class constructor. Bytecode does not have this limitation, instead the rule is that the super class constructor or another constructor in the same class must be called for the object before accessing the members. This should allow more freedom such as:

    • Create an instance of another object, store it in a local variable (or stack) and pass it as a parameter to super class constructor while still keeping the reference in that variable for other use.
    • Call different other constructors based on a condition. This should be possible: How to call a different constructor conditionally in Java?

    I have not tested these, so please correct me if I'm wrong.

    0 讨论(0)
  • 2020-12-04 05:07

    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.

    There are some features that are not produced by modern Java compilers, however:

    • The ACC_SUPER flag:

      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.

    • The jsr/ret bytecodes.

      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.

      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.

    0 讨论(0)
  • 2020-12-04 05:07

    Here are some features that can be done in Java bytecode but not in Java source code:

    • Throwing a checked exception from a method without declaring that the method throws it. The checked and unchecked exceptions are a thing which is checked only by the Java compiler, not the JVM. Because of this for example Scala can throw checked exceptions from methods without declaring them. Though with Java generics there is a workaround called sneaky throw.

    • Having two methods in a class that only differ in return type, as already mentioned in Joachim's answer: 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.

    0 讨论(0)
提交回复
热议问题