I want to open the Byte code (Java Binaries) generated by Java Compiler using some kind of editor, which allows me to view the byte code (Raw, but human understandable, in the format defined here) & modify things directly in the .class
file.
I have tried the javap
utility. But through javap
, I cannot change my .class File, also it doesn't seems to show the raw byte code
Also, I have seen de-compiler like JD Decompiler which gives me the code from the .class
File. But I am not interested in the source code, I want to view the byte code.
Also, I have tried GUI editors called dirtyJOE & JBE. This editor is quite a good one and fulfills half of my purpose. I can see various fields in the .class
file and edit my .class
file as well. But this also seems to be like a translator which decodes the byte code and show it on the UI for easy understanding. It doesn't shows me the raw byte code.
Is it even possible to go to the raw bytecode?
I might sound stupid, but I wanted to confirm this, to understand the Java Compiler and JVM properly.
It is possible to dump the raw byte code with javap -v
but to get all the information in the class file in a format you can edit I use ASM. The reason you wouldn't use this for editing is;
Its worth nothing that the byte code is just a compiled for of the Java code which is why they do much the same thing. The JVM is free to optimise it in any number of ways which makes understand the byte code not very useful if you want to understand how the JVM works or the code runs.
Thank you to @Antimony for suggested uses for manually written byte code. While some of them are valid they are either fairly advanced or obscure or have an alternative way of achieving the same thing.
Some ideas for
throw checked exceptions without declaring them,
Thread.currentThread().stop(checkedException);
catch checked exceptions without declaring them,
if (false) throw new CheckedException();
} catch(CheckedException ce) {
use identifiers invalid in Java
There are so many valid, but not so useful characters to use I would use one of those
if( ⁀ ‿ ⁀ == ⁀ ⁔ ⁀ || ¢ + ¢== ₡)
and
for (char ch = 0; ch < Character.MAX_VALUE; ch++)
if (Character.isJavaIdentifierPart(ch) && !Character.isJavaIdentifierStart(ch))
System.out.printf("%04x <%s>%n", (int) ch, "" + ch);
is valid code due to an invisible character in the identifier which causes the text to print backwards.
http://vanillajava.blogspot.co.uk/2012/09/hidden-code.html
http://vanillajava.blogspot.co.uk/2012/08/uses-for-special-characters-in-java-code.html
access fields before constructor call
I am pretty sure this causes a VerifyError (or it did when I tried it). Instead you can use
Object o = Unsafe.allocateInstance(clazz); // create without calling a constructor.
call different constructors conditionally
Again I have been able to place code between the object creation and the instance call, but there might be a way to get it to work. In Java you would write
MyClass mc = condition ? new MyClass(a) : new MyClass(a, b);
do exception handling on constructors.
Not sure what you mean here as you can catch or throw exceptions in constructors.
assign final fields more than once or not at all
You could use reflections instead and give final fields their default value. i.e. it not possible for a field to have no value.
have a strictfp constructor with nonstrictfp methods
That is an interesting one, but not one I have ever needed.
use laxer type checking
The byte code does allow different rules for type checking but they are easy to fall foul of with not so helpful VerifyErrors. You could do this but its very hard to get right IMHO.
throw exceptions from static initializer
You can throw unchecked exceptions already, and to throw checked ones you can use the trick above, however I usually wrap with in an AssertionError or the like.
use invokedynamic
You can use MethodHandles but they are rather clunky in Java 7. I hope that in Java 8 they will be more natural to use.
use subroutines
Interesting, I haven't tried this, but I am not sure what advantage they would give over method calls.
use unusual control flow
True, but this is more likely to confuse the JIT optimiser so the code can be slower as a result so may not give you the advantage you might hope for.
use old super call semantics
You could but I am not sure how useful that is.
use thread monitors
You can use
Unsafe.enterMonitor();
Unsafe.exitMonitor();
Unsafe.tryMonitorEnter();
initial values for fields.
I agree the compiler doesn't use these as much as I would expect but then again I am not sure they what difference it would make if it did.