Java Annotation 刷课笔记(二)
1.反射机制性能问题(安全检查)
1.1setAccessible
启用和禁用访问安全检查的开关,值为true,则指示反射的对象在使用时应该取消Java语言访问检查,值为false,则指示反射的对象应该实施Java语言的访问检查。
1.试验一,普通调用10亿次,需要约2258ms。
2.试验二,普通反射invoke调用10亿次,需要接近普通调用的30倍速度,大约62kms。(这就是反射的缺点)
3.试验三,设置通过安全检查,则,提高约4倍速度,10kms左右。
反射操作泛型
2.反射操作泛型
2.1.介绍
- Java采用泛型擦除机制引入泛型,Java中的泛型仅仅是编译器javac使用的,确保数据的安全性,避免反射转换的麻烦。但是,一旦编译完成,所有与泛型有关的类型全部擦除。
- 为了通过反射操作类型,硬核实际需要,Java新增了ParameterizedType,GenericArrayType,TypeVariable和WildcardType几种类型来代表不能归并到Class类型但是又和原始类型齐名的类型。
- ParaneterizedType 参数化类型,如Colloection<String>
- GenericArrayType 参数类型或者变量数组
- TypeVariable 各种类型变量的公共父接口
- WildcardType 通配泛型表达式,比如?, ? extends Number, ? super Integer
public void test01(Map<Integer, String> map, List<User> list) { System.out.println("aa"); }
public static void print() throws NoSuchMethodException { Method m = A.class.getMethod("test01", Map.class, List.class); Type[] t = m.getGenericParameterTypes(); for (Type t1 : t) { Type[] genericTypes = ((ParameterizedType) t1).getActualTypeArguments(); for (Type ty : genericTypes) { System.out.println(ty); } } }
3.动态编译
3.1.介绍
Java6.0引入动态编译机制
3.2.动态编译应用场景
- 浏览器编写java代码,上传服务器编译和运行的在线评测系统
- 服务器动态加载文件进行编译
3.3.编译的两种做法
- 通过Runtime调用javac,启动新的进程操作动态(运行编译后内容)
Runtime run=Runtime.getRuntime(); Process process=run.exec("java -cp d:/myjava/ HelloWorld.java");
- 通过JavaCompile动态编译
public static int compileFile(String sourceFile){ JavaCompiler compiler=ToolProvider.getSystem.JavaCompiler(); int result=compiler.run(null,null,null,sourceFile); System.out.println(result==0?"编译成功":"编译失败"); return result; }
3.4.动态运行编译后的程序
- 3.4.1.process可以获取一个输入流(3.3.1中),可以用BufferdedRead进行打印结果值
- 3.4.2.用类加载器加载类,获取方法执行
4.脚本引擎执行javascript代码
4.1使用ScriptEngineManager
ScriptEngineManager sem=new ScriptEngineManager(); ScriptEngine engine=sem.getEngineByName("javascript"); engint.put("msg","a good man"); engine.eval("计算");
5.javaassist库介绍
5.1.介绍
- 可以进行字节码操作
5.2.运行操作字节码可以实现
- 动态生成新的类
- 动态改变类的结构
5.3.优势
- 比反射开销小,性能高
5.4常见字节码操作类库
- BAEL
Byte Code Engineering Library, 这是Apache Software Foundation的Jakarta项目的一部分,BCEL是Java Classworking钢钒使用的一种框架,它可以让您深入JVM汇编语言进行类操作,BCEL与Javaassist有着不同处理字节的方法,BCEL实际JVM指令操作BCEL,拥有丰富的JVM指令支持编译源码级别工作
- ASM
一个轻量级的操作Java字节码的框架,直接注射剂JVM底层的操作和指令
- CGLIB(Code Generation Library)
一个强大的,高性能,高质量的Code生成类库,基于ASM实现
- JavaAssist
编译和创建Java字节码的类库,性能较ASM差,跟CGLIB差不多,但是使用简单,很多开源框架都适用