动态编译(javassist及Runtime的学习)

package dynamicCompilier;

import java.io.IOException;

public class RunTimeDemol {
        //使用Runtime动态编译
	public static void main(String[] args) throws IOException {
		Runtime runtime = Runtime.getRuntime();
		Process process = runtime.exec("javac -cp C:\\Users\\闻人哲杰\\Desktop\\Hello.java");
		
	}
}
package dynamicCompilier;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

public class JavaCompilierDemol {
public static void main1(String[] args) throws Exception {
	//使用JavaCompiler编译
	JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
	System.out.println(compiler);//此处可能会出现打印null问题 见:https://blog.csdn.net/liu578182160/article/details/25103905
	int restult = compiler.run(null, null, null, "C:\\Users\\闻人哲杰\\Desktop\\Hello.java");
	System.out.println(restult == 0?"编译成功":"编译失败");
	//使用Runtime执行
	Runtime runtime = Runtime.getRuntime();														//注意此处
	Process process= runtime.exec("java -cp C:\\Users\\闻人哲杰\\Desktop Hello");
	InputStream inputStream = process.getInputStream();
	BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
	String str = "";
	while((str = br.readLine())!=null) {
		System.out.println(str);
	}
	
	
}
//使用反射执行Java文件
	public static void main(String[] args) {
		try {
			URL[] urls = new URL[] {new URL("file:\\"+"C:\\Users\\闻人哲杰\\Desktop\\")};
			URLClassLoader loader = new URLClassLoader(urls);
			Class clazz = loader.loadClass("Hello");
			//调用加载类的main方法
			Method m = clazz.getDeclaredMethod("main",String[].class);
			//main方法是静态方法,反射调用静态方法第一个参数可设为null,注意参数为数组类型是,需加(Object)强转,否则回报类型不匹配问题
			m.invoke(null,(Object)new String[] {});
			/*eg:利用反射调用这个方法public dtatic void test(String[] str)
			 * 若为invoke(null,new String[]{"aa","bb"})其实会编译成m.invoke(null,"aa","bb"),则会发生
			 * 类型不匹配问题,若要避免这个问题,需要加上(Object)
			 */
			
		}catch(Exception e) {
			e.printStackTrace();
		}
		
	}
}
package dynamicCompilier;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;

/* 详情见https://blog.csdn.net/top_code/article/details/51708043
 * JAVA动态性的两种常见实现方式:字节码操作,反射
 * 运行时操作字节码可以让我们实现如下功能:动态生成新的类,动态改变某个类的结构(添加,删除,修改,新的属性/方法)
 * 优势:比反射开销小。javaasist性能高于反射,低于ASM
 * javassist的最外层的API和反射包中的API颇为类似,它主要由CtClass,CtMetho以及CtMethod几个类组成。
 */
public class ByteCodeDemol01 {
	//利用javassist生成一个新类
	public static void main(String[] args) {
		ClassPool pool = ClassPool.getDefault();
		CtClass ctclass = pool.makeClass("dynamicCompilier.emp");
		
		try {
			
			//创建属性
			CtField ctfield1 = CtField.make("private int empno;",ctclass);
			CtField ctfield2 = CtField.make("private String ename;", ctclass);
			ctclass.addField(ctfield1);
			ctclass.addField(ctfield2);
			//创建方法
			CtMethod ctmethod1 = CtMethod.make("public int getEmpno(){return this.empno;}",ctclass);
			CtMethod ctmethod2 = CtMethod.make("public void setEmpno(String empno){this.empno = empno;}", ctclass);
			ctclass.addMethod(ctmethod1);
			ctclass.addMethod(ctmethod2);
			//创建有参构造器                                                                  							 
			CtConstructor constructor = new CtConstructor(new CtClass[]{CtClass.intType,pool.get("java.lang.String")},ctclass);
			ctclass.addConstructor(constructor);
			constructor.setBody("{this.empno = empno;this.ename = ename;}");
			ctclass.writeFile("D:\\dynamic");//将上面构造好的类写入文件	
			System.out.println("生成新类完成");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	} 
}
package dynamicCompilier;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;

public class ByteCodeDemol02 {
	//测试javassist处理类的基本方法
	public static void main1(String[] args) throws Exception {
		ClassPool pool = ClassPool.getDefault();
		CtClass ctclass = pool.get("dynamicCompilier.Emp");
		
		byte[] bt = ctclass.toBytecode();
		//System.out.println(Arrays.toString(bt));
		
		System.out.println(ctclass.getName());//包名+类名
		System.out.println(ctclass.getSimpleName());//类名
		System.out.println(ctclass.getSuperclass());//获得父类
		System.out.println(ctclass.getInterfaces());//获得接口
		
	}
	public static void main2(String[] args) throws Exception {
		ClassPool pool = ClassPool.getDefault();
		CtClass ctclass = pool.get("dynamicCompilier.Emp");
		CtMethod ctmethod = CtNewMethod.make("public int add(int a,int b){System.out.println(\"return a+b\");return a+b;}",ctclass);
		CtMethod ctmethod1 = new CtMethod(CtClass.intType, "add", new CtClass[] {CtClass.intType,CtClass.intType},ctclass);
		ctmethod1.setModifiers(Modifier.PUBLIC);                    //占位符
		ctmethod1.setBody("{System.out.println(\"return a+b\");return $1+$2;}");
		//ctclass.addMethod(ctmethod);
		ctclass.addMethod(ctmethod1);
		//通过反射调用方法
		Class<?> clazz = ctclass.toClass();
		Object newInstance = clazz.newInstance();
		Method addMethod = clazz.getDeclaredMethod("add",int.class,int.class);
		Object invoke = addMethod.invoke(newInstance, 300,300);
		System.out.println(invoke);
		
		
		
		
	}
	
	public static void main(String[] args) throws Exception {
		ClassPool pool = ClassPool.getDefault();
		CtClass ctclass = pool.get("dynamicCompilier.Emp");
		CtMethod declaredMethod = ctclass.getDeclaredMethod("sayHello");
		declaredMethod.insertBefore("System.out.println(\"begin\")");
		declaredMethod.insertAt(26, "System.out.println(\"在26行插入语句\");");
		declaredMethod.insertAfter("System.out.println(\"end\")");
		//通过反射调用方法
			Class<?> clazz = ctclass.toClass();
			Object newInstance = clazz.newInstance();
			Method addMethod = clazz.getDeclaredMethod("sayHello",null);
			Object invoke = addMethod.invoke(newInstance);
		
				
	}
}



package dynamicCompilier;

public class Emp {
	private String name;
	private int empno;
	private int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getEmpno() {
		return empno;
	}
	public void setEmpno(int empno) {
		this.empno = empno;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public void sayHello() {
		System.out.println("Hello");
	}
	public Emp(String name, int empno, int age) {
		super();
		this.name = name;
		this.empno = empno;
		this.age = age;
	}
	public Emp() {
		super();
	}
	
	
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值