Using a metaprogramming library called javassist I tried to rewrite the class that I actually created.
You can use it when you are using the library and think it's shit. (Mysterious log is output, etc ...)
I'm using gradle.
build.gradle
...
dependencies {
...
    compile group: 'org.javassist', name: 'javassist', version: '3.15.0-GA'
}
Actually rewrite the prepared class called User, Add a field called money.
data/User.java
package data;
public class User {
    private String name;
    private int age;
    private float height;
    private float width;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public String getUserInfo() {
        return "name: " + name + ", age: " + age;
    }
}
Main.java
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.Modifier;
public class Test {
    public static void main(String[] args) {
        try {
            //Get the pool for all classes.
            ClassPool pool = ClassPool.getDefault();
            //Full data of package name and class name.Search for User
            //If not found, an exception will be thrown.
            CtClass ctc = pool.get("data.User");
            //Specify the field type, field name, and declaration destination as arguments.
            CtField field = new CtField(CtClass.intType, "money", ctc);
            //Specify field qualifier
            //If there are multiple modifiers|I will add it with.
            // field.setModifiers(Modifier.STATIC | Modifier.PRIVATE);
            field.setModifiers(Modifier.PRIVATE);
            //Add field.
            ctc.addField(field);
            //Get the defined method.
            CtMethod method = ctc.getDeclaredMethod("getUserInfo");
            //Changed to output money by replacing the inside of the method.
            method.setBody("return \"name: \" + name + \", age: \" + age + \", money: \" + money;");
            //Overwrite class in class loader.
            Class cls = ctc.toClass(ClassLoader.getSystemClassLoader(), AsmTest.class.getProtectionDomain());
            //Instantiate a class with reflection.
            User ins = (User) cls.newInstance();
            ins.setName("Bob");//Specify Bob for name.
            //Since money is added after compilation, get it by reflection.
            Field f = cls.getDeclaredField("money");
            //Changed accessibility.
            //If private or protected, set it to true so that it can be accessed.
            f.setAccessible(true);
            //Change the money field to 1500 with int.
            f.setInt(ins, 1500);
            //Actual output.
            System.out.println("name: " + ins.getName());
            System.out.println("money: " + f.getInt(ins));
            System.out.println(ins.getUserInfo());
        } catch (Exception e) {
            //Output an error.
            System.out.println(e);
        }
    }
}
Result is...
name: Bob
money: 1500
name: Bob, age: 0, money: 1500
How, the field called money is increasing, You can change the value.
I introduced only the addition of this field, but since there are various other functions Please use it by all means.
javassist https://github.com/jboss-javassist/javassist
Recommended Posts