1 ClassPool pool = ClassPool.getDefault(); 2 //会从classpath中查询该类 3 CtClass cc = pool.get("test.Rectangle"); 4 //设置.Rectangle的父类 5 cc.setSuperclass(pool.get("test.Point")); 6 //输出.Rectangle.class文件到该目录中 7 cc.writeFile("c://"); 8 //输出成二进制格式 9 //byte[] b=cc.toBytecode(); 10 //输出并加载class 类,默认加载到当前线程的ClassLoader中,也可以选择输出的ClassLoader。 11 //Class clazz=cc.toClass();
1 ClassPool pool = ClassPool.getDefault(); 2 CtClass cc = pool.makeClass("Point"); 3 //新增方法 4 cc.addMethod(m); 5 //新增Field 6 cc.addField(f);
1 CtClasss cc = ...; 2 : 3 cc.writeFile(); 4 cc.defrost(); 5 cc.setSuperclass(...); // OK since the class is not frozen.
1 CtClasss cc = ...; 2 cc.stopPruning(true); 3 : 4 cc.writeFile(); // convert to a class file. 5 // cc没有被释放
1 //默认加载方式如pool.insertClassPath(new ClassClassPath(this.getClass())); 2 ClassPool pool = ClassPool.getDefault(); 3 //从file加载classpath 4 pool.insertClassPath("/usr/local/javalib") 5 //从URL中加载 6 ClassPath cp = new URLClassPath("www.javassist.org", 80, "/java/", "org.javassist."); 7 pool.insertClassPath(cp); 8 //从byte[] 中加载 9 byte[] b = a byte array; 10 String name = class name; 11 cp.insertClassPath(new ByteArrayClassPath(name, b)); 12 //可以从输入流中加载class 13 InputStream ins = an input stream for reading a class file; 14 CtClass cc = cp.makeClass(ins);
1 CtClass cc = ... ; 2 cc.writeFile(); 3 cc.detach();
1 //ClassPool(true) 会默认加载Jvm的ClassPath 2 ClassPool cp = new ClassPool(true); 3 // if needed, append an extra search path by appendClassPath()
1 ClassPool parent = ClassPool.getDefault(); 2 ClassPool child = new ClassPool(parent); 3 child.insertClassPath("./classes");
1 ClassPool pool = ClassPool.getDefault(); 2 CtClass cc = pool.get("Point"); 3 cc.setName("Pair"); 4 //重新在classpath加载 5 CtClass cc1 = pool.get("Point");
1 ClassPool pool = ClassPool.getDefault(); 2 CtClass cc = pool.get("Point"); 3 cc.writeFile(); // has frozened 4 //cc.setName("Pair"); wrong since writeFile() has been called. 5 CtClass cc2 = pool.getAndRename("Point", "Pair");
1 // 当Hello未加载的时候,下面是可以运行的。 2 ClassPool cp = ClassPool.getDefault(); 3 CtClass cc = cp.get("Hello"); 4 Class c = cc.toClass(); 5 //下面这种情况,由于Hello2已加载,所以会出错 6 Hello2 h=new Hello2(); 7 CtClass cc2 = cp.get("Hello2"); 8 Class c2 = cc.toClass();//这里会抛出java.lang.LinkageError 异常 9 //解决加载问题,可以指定一个未加载的ClassLoader 10 Class c3 = cc.toClass(new MyClassLoader());
1 ClassPool pool = ClassPool.getDefault(); 2 Loader cl = new Loader(pool); 3 CtClass ct = pool.get("test.Rectangle"); 4 ct.setSuperclass(pool.get("test.Point")); 5 Class c = cl.loadClass("test.Rectangle"); 6 Object rect = c.newInstance(); :
1 //Translator 为监听器 2 public class MyTranslator implements Translator { 3 void start(ClassPool pool) 4 throws NotFoundException, CannotCompileException {} 5 void onLoad(ClassPool pool, String classname) 6 throws NotFoundException, CannotCompileException 7 { 8 CtClass cc = pool.get(classname); 9 cc.setModifiers(Modifier.PUBLIC); 10 } 11 } 12 //示例 13 public class Main2 { 14 public static void main(String[] args) throws Throwable { 15 Translator t = new MyTranslator(); 16 ClassPool pool = ClassPool.getDefault(); 17 Loader cl = new Loader(); 18 cl.addTranslator(pool, t); 19 cl.run("MyApp", args); 20 } 21 } 22 //输出 23 % java Main2 arg1 arg2...
ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.get("java.lang.String"); CtField f = new CtField(CtClass.intType, "hiddenValue", cc); f.setModifiers(Modifier.PUBLIC); cc.addField(f); cc.writeFile("."); //运行脚本 % java -Xbootclasspath/p:. MyApp arg1 arg2...
$0, $1, $2, ... | this and actual parameters |
$args | An array of parameters. The type of $args is Object[]. |
$$ | All actual parameters.For example, m($$) is equivalent to m($1,$2,...) |
$cflow(...) | cflow variable |
$r | The result type. It is used in a cast expression. |
$w | The wrapper type. It is used in a cast expression. |
$_ | The resulting value |
$sig | An array of java.lang.Class objects representing the formal parameter types |
$type | A java.lang.Class object representing the formal result type. |
$class | A java.lang.Class object representing the class currently edited. |
1 //实际方法 2 void move(int dx, int dy) 3 //javassist 4 CtMethod m = cc.getDeclaredMethod("move"); 5 //打印dx,和dy 6 m.insertBefore("{ System.out.println($1); System.out.println($2); }");
1 //原方法 2 move(String a,String b) 3 move($$) 相当于move($1,$2) 4 如果新增一个方法,方法含有move的所有参数,则可以这些写: 5 exMove($$, context) 相当于 exMove($1, $2, context)
1 //原方法 2 int fact(int n) { 3 if (n <= 1) 4 return n; 5 else 6 return n * fact(n - 1); 7 } 8 //javassist调用 9 CtMethod cm = ...; 10 //这里代表使用了cflow 11 cm.useCflow("fact"); 12 //这里用了cflow,说明当深度为0的时候,就是开始当第一次调用fact的方法的时候,打印方法的第一个参数 13 cm.insertBefore("if ($cflow(fact) == 0)" 14 + " System.out.println(\"fact \" + $1);");
1 CtMethod m = ...; 2 CtClass etype = ClassPool.getDefault().get("java.io.IOException"); 3 m.addCatch("{ System.out.println($e); throw $e; }", etype);
1 try { 2 the original method body 3 } 4 catch (java.io.IOException e) { 5 System.out.println(e); 6 throw e; 7 }
$0, $1, $2, ... | this and actual parameters |
$args | An array of parameters. The type of $args is Object[]. |
$$ | All actual parameters.For example, m($$) is equivalent to m($1,$2,...) |
$cflow(...) | cflow variable |
$r | The result type. It is used in a cast expression. |
$w | The wrapper type. It is used in a cast expression. |
$sig | An array of java.lang.Class objects representing the formal parameter types |
$type | A java.lang.Class object representing the formal result type. |
$class | A java.lang.Class object representing the class currently edited. |
1 CtMethod cm = ... ; 2 cm.instrument( 3 new ExprEditor() { 4 public void edit(MethodCall m) 5 throws CannotCompileException 6 { 7 if (m.getClassName().equals("Point") 8 && m.getMethodName().equals("move")) 9 m.replace("{ $1 = 0; $_ = $proceed($$); }"); 10 } 11 });
$0 | The target object of the method call. This is not equivalent to this, which represents the caller-side this object. $0 is null if the method is static. |
$1, $2, ... | The parameters of the method call. |
$_ | The resulting value of the method call. |
$r | The result type of the method call. |
$class | A java.lang.Class object representing the class declaring the method. |
$sig | An array of java.lang.Class objects representing the formal parameter types |
$type | A java.lang.Class object representing the formal result type. |
$proceed | The name of the method originally called in the expression. |
$0 | The target object of the constructor call. This is equivalent to this. |
$1, $2, ... | The parameters of the constructor call. |
$class | A java.lang.Class object representing the class declaring the constructor. |
$sig | An array of java.lang.Class objects representing the formal parameter types. |
$proceed | The name of the constructor originally called in the expression. |
$0 | The object containing the field accessed by the expression. This is not equivalent to this. this represents the object that the method including the expression is invoked on. $0 is null if the field is static. |
$1 | The value that would be stored in the field if the expression is write access. Otherwise, $1 is not available. |
$_ | The resulting value of the field access if the expression is read access. Otherwise, the value stored in $_ is discarded. |
$r | The type of the field if the expression is read access. Otherwise, $r is void. |
$class | A java.lang.Class object representing the class declaring the field. |
$type | A java.lang.Class object representing the field type. |
$proceed | The name of a virtual method executing the original field access. . |
$0 | null |
$1, $2, ... | The parameters to the constructor. |
$_ | The resulting value of the object creation. A newly created object must be stored in this variable. |
$r | The type of the created object. |
$sig | An array of java.lang.Class objects representing the formal parameter types |
$type | A java.lang.Class object representing the class of the created object. |
$proceed | The name of a virtual method executing the original object creation. . |
$0 | null |
$1, $2, ... | The size of each dimension. |
$_ | The resulting value of the object creation. A newly created array must be stored in this variable. |
$r | The type of the created object. |
$type | A java.lang.Class object representing the class of the created array . |
$proceed | The name of a virtual method executing the original array creation. . |
$0 | null |
$1 | The value on the left hand side of the original instanceof operator. |
$_ | The resulting value of the expression. The type of $_ is boolean. |
$r | The type on the right hand side of the instanceof operator. |
$type | A java.lang.Class object representing the type on the right hand side of the instanceof operator. |
$proceed | The name of a virtual method executing the original instanceof expression. It takes one parameter (the type is java.lang.Object) and returns true if the parameter value is an instance of the type on the right hand side of the original instanceof operator. Otherwise, it returns false. |
$0 | null |
$1 | The value the type of which is explicitly cast. |
$_ | The resulting value of the expression. The type of $_ is the same as the type after the explicit casting, that is, the type surrounded by ( ). |
$r | the type after the explicit casting, or the type surrounded by ( ). |
$type | A java.lang.Class object representing the same type as $r. |
$proceed | The name of a virtual method executing the original type casting. It takes one parameter of the type java.lang.Object and returns it after the explicit type casting specified by the original expression. |
$1 | The exception object caught by the catch clause. |
$r | the type of the exception caught by the catch clause. It is used in a cast expression. |
$w | The wrapper type. It is used in a cast expression. |
$type | A java.lang.Class object representing the type of the exception caught by the catch clause. |
1 CtClass point = ClassPool.getDefault().get("Point"); 2 CtMethod m = CtNewMethod.make( 3 "public int xmove(int dx) { x += dx; }", 4 point); 5 point.addMethod(m); 6 7 在方法中调用其他方法,例如: 8 CtClass point = ClassPool.getDefault().get("Point"); 9 CtMethod m = CtNewMethod.make( 10 "public int ymove(int dy) { $proceed(0, dy); }", 11 point, "this", "move"); 12 其效果如下: 13 public int ymove(int dy) { this.move(0, dy); }
1 CtClass cc = ... ; 2 CtMethod m = new CtMethod(CtClass.intType, "move", 3 new CtClass[] { CtClass.intType }, cc); 4 cc.addMethod(m); 5 m.setBody("{ x += $1; }"); 6 cc.setModifiers(cc.getModifiers() & ~Modifier.ABSTRACT); 7 Since Javassist makes a class abstract if an abstract method is added to the class, you have to explicitly change the class back to a non-abstract one after calling setBody().
1 CtClass cc = ... ; 2 CtMethod m = CtNewMethod.make("public abstract int m(int i);", cc); 3 CtMethod n = CtNewMethod.make("public abstract int n(int i);", cc); 4 cc.addMethod(m); 5 cc.addMethod(n); 6 m.setBody("{ return ($1 <= 0) ? 1 : (n($1 - 1) * $1); }"); 7 n.setBody("{ return m($1); }"); 8 cc.setModifiers(cc.getModifiers() & ~Modifier.ABSTRACT);
1 CtClass point = ClassPool.getDefault().get("Point"); 2 CtField f = new CtField(CtClass.intType, "z", point); 3 point.addField(f); 4 //point.addField(f, "0"); // initial value is 0. 5 或者: 6 CtClass point = ClassPool.getDefault().get("Point"); 7 CtField f = CtField.make("public int z = 0;", point); 8 point.addField(f);
1 调用removeField()或者removeMethod()。
1 //注解 2 public @interface Author { 3 String name(); 4 int year(); 5 } 6 //javassist代码 7 CtClass cc = ClassPool.getDefault().get("Point"); 8 Object[] all = cc.getAnnotations(); 9 Author a = (Author)all[0]; 10 String name = a.name(); 11 int year = a.year(); 12 System.out.println("name: " + name + ", year: " + year);
1 ClassPool pool = ClassPool.getDefault(); 2 pool.importPackage("java.awt"); 3 CtClass cc = pool.makeClass("Test"); 4 CtField f = CtField.make("public Point p;", cc); 5 cc.addField(f);
原文:http://www.cnblogs.com/sunfie/p/5154246.html