|
2 | 2 |
|
3 | 3 | This is a Java class file manipulation library that, unlike other bytecode libraries, directly deals with the constructs in the class file without any abstraction. It is still unfinished. |
4 | 4 |
|
| 5 | +## Examples |
| 6 | +A generic example can be found [here](https://github.com/Seggan/JavaClassLib/blob/master/src/test/java/io/github/seggan/javaclasslib/tests/Test.java). |
| 7 | + |
| 8 | +##### Creating a class |
| 9 | +This will create a basic class named `TheName` extending `some.super.Class` compiled with Java version 11. Note that java versions less than 8 are not supported and using one will throw an exception. |
| 10 | +```java |
| 11 | +JavaClass aClass = new JavaClass("TheName", "some.super.Class", 11); |
| 12 | +aClass.setAccessFlags(ClassAccessFlags.PUBLIC); |
| 13 | +``` |
| 14 | + |
| 15 | +##### Adding constant pool entries |
| 16 | +Assuming we have the code from above, adding a constant pool entry is simple. For example, here we add a `UTF8_info` constant pool entry. |
| 17 | +```java |
| 18 | +UTF8Entry entry = new UTF8Entry(aClass.getConstantPool(), "Write whatever you want in here"); |
| 19 | +``` |
| 20 | +The entry will automatically add itself to the constant pool on creation. |
| 21 | + |
| 22 | +##### Adding methods |
| 23 | +Here comes the juicy part: methods. Adding a method is slightly more complex. |
| 24 | +```java |
| 25 | +Method m = new Method(new UTF8Entry(aClass.getConstantPool(), "youMethodName"), new UTF8Entry(aClass.getConstantPool(), "(some.Type;)V")); |
| 26 | +m.setAccessFlags(MethodAccessFlags.PUBLIC); |
| 27 | +aClass.getMethods().add(m); |
| 28 | +``` |
| 29 | + |
| 30 | +##### Bytecode |
| 31 | +Finally, bytecode! In Java, bytecode goes into a thing called a *code attribute*, which then goes into the method. Here's a sample: |
| 32 | +```java |
| 33 | +List<JvmInstructionImpl> instructions = Arrays.asList( |
| 34 | + JvmInstructions.ALOAD.create(0), |
| 35 | + JvmInstructions.DUP.create() |
| 36 | +); |
| 37 | +CodeAttribute code = new CodeAttribute(new UTF8Entry(aClass.getConstantPool(), "Code"), 5, 2, instructions); |
| 38 | +m.getAttributes().add(code); |
| 39 | +``` |
| 40 | +The code attribute has 4 arguments: a `UTF8Entry` pointing to the value `Code` (this is very important!), the max stack size, the max local variable size, and a list of bytecode instructions. In this case the instructions are `aload 0, dup` |
| 41 | + |
| 42 | +##### Writing |
| 43 | +What's the point of having a Java class if you can't write it? The `JavaClass` has a method `write(OutputStream out)` that writes the class in byte form. It can be used with a `FileOutputStream`, `ByteArrayOutputStream`, and all the other variants. |
| 44 | + |
5 | 45 | ## Todo |
6 | 46 | - Add the rest of the bytecode instructions |
7 | 47 | - Add more attributes |
8 | | -- Add interface, field, and attribute capabilities to classes |
| 48 | +- Add interface, field, and attribute capabilities to classes |
| 49 | +- Add exception tables to the code attribute |
0 commit comments