Utilisation d'une bibliothèque de méta-programmation appelée javassist J'ai essayé de réécrire la classe que j'ai réellement créée.
Vous pouvez l'utiliser lorsque vous utilisez la bibliothèque et pensez que c'est de la merde. (Un journal mystérieux est sorti, etc ...)
J'utilise gradle.
build.gradle
...
dependencies {
...
compile group: 'org.javassist', name: 'javassist', version: '3.15.0-GA'
}
Réécrivez en fait la classe préparée appelée User, Ajoutez un champ appelé argent.
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 {
//Obtenez des piscines pour toutes les classes.
ClassPool pool = ClassPool.getDefault();
//Données complètes du nom du package et du nom de la classe.Rechercher un utilisateur
//S'il n'est pas trouvé, une exception sera levée.
CtClass ctc = pool.get("data.User");
//Spécifiez le type de champ, le nom du champ et la destination de la déclaration dans les arguments.
CtField field = new CtField(CtClass.intType, "money", ctc);
//Spécifier le modificateur de champ
//S'il y a plusieurs modificateurs|Je vais l'ajouter avec.
// field.setModifiers(Modifier.STATIC | Modifier.PRIVATE);
field.setModifiers(Modifier.PRIVATE);
//Ajouter le champ.
ctc.addField(field);
//Obtenez la méthode définie.
CtMethod method = ctc.getDeclaredMethod("getUserInfo");
//Changé pour produire de l'argent en remplaçant l'intérieur de la méthode.
method.setBody("return \"name: \" + name + \", age: \" + age + \", money: \" + money;");
//Écraser la classe dans le chargeur de classe.
Class cls = ctc.toClass(ClassLoader.getSystemClassLoader(), AsmTest.class.getProtectionDomain());
//Créez une instance de la classe avec réflexion.
User ins = (User) cls.newInstance();
ins.setName("Bob");//Spécifiez Bob comme nom.
//Puisque l'argent est ajouté après la compilation, obtenez-le par réflexion.
Field f = cls.getDeclaredField("money");
//Accessibilité modifiée.
//S'il est privé ou protégé, définissez-le sur true pour qu'il soit accessible.
f.setAccessible(true);
//Changez le champ money à 1500 avec int.
f.setInt(ins, 1500);
//Sortie réelle.
System.out.println("name: " + ins.getName());
System.out.println("money: " + f.getInt(ins));
System.out.println(ins.getUserInfo());
} catch (Exception e) {
//Affiche une erreur.
System.out.println(e);
}
}
}
Le résultat est ...
name: Bob
money: 1500
name: Bob, age: 0, money: 1500
Comment, le domaine appelé argent augmente, Vous pouvez changer la valeur.
Je n'ai introduit que l'ajout de ce champ, mais comme il y a diverses autres fonctions Veuillez l'utiliser par tous les moyens.
javassist https://github.com/jboss-javassist/javassist
Recommended Posts