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();
}
}