回覆列表
  • 1 # 淘寶客老妖

    可以的,你用 javassist, cglib 或者更為底層的工具 ASM 都是可以。ASM 的話相對複雜一些,參考程式碼:下面這個是用 ASM 工具為 Student 類新增一個 public String 型別的 address 屬性:1,需要新增屬性的原始類:Student.javaJava code?public class Student {private int age;private String name;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}}2,新增屬性的介面卡:AddFieldAdapter.javaJava code?import org.objectweb.asm.ClassAdapter;import org.objectweb.asm.ClassVisitor;import org.objectweb.asm.FieldVisitor;public class AddFieldAdapter extends ClassAdapter {private int accessModifier;private String name;private String desc;private boolean isFieldPresent;public AddFieldAdapter(ClassVisitor cv, int accessModifier, String name, String desc) {super(cv);this.accessModifier = accessModifier;this.name = name;this.desc = desc;}@Overridepublic FieldVisitor visitField(int access, String name, String desc,String signature, Object value) {if (name.equals(this.name)) {isFieldPresent = true;}return cv.visitField(access, name, desc, signature, value);}@Overridepublic void visitEnd() {if (!isFieldPresent) {FieldVisitor fv = cv.visitField(accessModifier, name, desc, null, null);if (fv != null) {fv.visitEnd();}}cv.visitEnd();}}3,新增屬性的工具 AddField.javaJava code?import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import org.objectweb.asm.ClassAdapter;import org.objectweb.asm.ClassReader;import org.objectweb.asm.ClassWriter;import org.objectweb.asm.Opcodes;public class AddField {private Class clazz = null;private ClassReader cr = null;private ClassWriter cw = null;private ClassAdapter ca = null;private File classFile = null;private final static String CLASS_FILE_SUFFIX = ".class";public AddField(Class clazz) {this.clazz = clazz;}/*** 新增一個 public 的類成員* @param fieldName 類成員名* @param fieldDesc 類成員型別描述*/public void addPublicField(String fieldName, String fieldDesc) {if(cr == null) {try {cr = new ClassReader(clazz.getCanonicalName());} catch (IOException e) {e.printStackTrace();}cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);}if(ca == null) {ca = new AddFieldAdapter(cw, Opcodes.ACC_PUBLIC, fieldName, fieldDesc);} else {ca = new AddFieldAdapter(ca, Opcodes.ACC_PUBLIC, fieldName, fieldDesc);}}/*** 將位元組碼寫入類的 .class 檔案**/public void writeByteCode() {cr.accept(ca, ClassReader.SKIP_DEBUG);byte[] bys = cw.toByteArray();OutputStream os = null;try {os = new FileOutputStream(getFile());os.write(bys);} catch (IOException e) {e.printStackTrace();} finally {try {os.close();} catch (IOException e) {e.printStackTrace();}}}/*** 獲得類檔案的 File 物件* @return*/private File getFile() {if(classFile == null) {StringBuffer sb = new StringBuffer();sb.append(clazz.getResource("/")).append(clazz.getCanonicalName().replace(".", File.separator)).append(CLASS_FILE_SUFFIX);classFile = new File(sb.substring(6));}return classFile;}}

  • 中秋節和大豐收的關聯?
  • 爽膚水塗上去之後會有點灼熱的感覺是正常現象嗎?過了一會就又不會?