反射图示:

简单上代码了解一下:

1.实体类

 1 package com.reflection;
 2
 3 public class Student {
 4     //学生实体类,包含编号,名字,所属班级的属性
 5     private int id;
 6     private String name;
 7     private String cname;
 8
 9     public Student() {
10         super();
11     }
12     //构造器
13     public Student(int id, String name, String cname) {
14         super();
15         this.id = id;
16         this.name = name;
17         this.cname = cname;
18     }
19
20     public int getId() {
21         return id;
22     }
23     public void setId(int id) {
24         this.id = id;
25     }
26
27     public String getName() {
28         return name;
29     }
30     public void setName(String name) {
31         this.name = name;
32     }
33
34     public String getCname() {
35         return cname;
36     }
37     public void setCname(String cname) {
38         this.cname = cname;
39     }
40
41 }

2.方法示例:

  1 package com.reflection;
  2
  3 import java.lang.reflect.Constructor;
  4 import java.lang.reflect.Field;
  5 import java.lang.reflect.InvocationTargetException;
  6 import java.lang.reflect.Method;
  7 import java.lang.reflect.ParameterizedType;
  8 import java.lang.reflect.Type;
  9 import java.util.ArrayList;
 10 import java.util.List;
 11
 12 import javax.script.ScriptEngine;
 13 import javax.script.ScriptEngineManager;
 14 import javax.script.ScriptException;
 15 import javax.tools.JavaCompiler;
 16 import javax.tools.ToolProvider;
 17
 18 import com.sun.javafx.collections.MappingChange.Map;
 19
 20 /*
 21  * Java动态性:
 22  * 动态语言:
 23  * 程序运行时,可以改变程序结构或变量类型,Java并非动态语言,但其拥有动态性,利用反射机制以及字节码操作获得类似动态语言的特性.
 24  * 一.反射机制:可以于运行时加载,探知,使用编译期间完全未知的类。
 25  *  (1)PS:程序在运行状态中,可以动态的加载一个只有名称的类,对于任意一个已加载的类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性
 26  *  (2)操作方式:Class c=Class.forName("com.reflection.Reflect");
 27  *  (3)反射:加载完类之后,在堆内存中会产生一个Class类型的对象(一个类只有一个Class对象),该对象包含了完整的类的结构信息,通过这个对象可以看到类的结构,这便是反射。
 28  *  (4)Class类是Reflection的根源:针对任何想要动态加载,运行的类,唯有先获得相应的Class对象。
 29  *  (5)获取Class对象的三种方式: getClass(),Class.forName(),.class语法
 30  *  (6)反射机制的常见作用:
 31  *  动态加载类,动态获取类的信息(属性,方法,构造器)/动态构造对象/动态调用类和对象的任意方法及构造器/
 32  *  动态调用和处理属性/获取泛型信息/处理注解
 33  *  (7)反射机制的性能问题:
 34  *  利用反射执行类方法执行速度大概为类普通方法执行速度的1/30,也就是很慢,效率低,加上setAccessible()后可提高效率
 35  *  setAccessible():启用和禁用访问安全检查的开关,值为true,则表示取消访问安全检查,反之
 36  *
 37  * 二.动态编译:
 38  * 动态编译的两种做法:
 39  * (1)通过Runtime调用javac,启动新的进程去操作
 40  * ->Runtime run=Runtime.getRuntime();
 41  *   Process process=run.exec("java -cp +类文件绝对路径");
 42  * (2)通过JavaCompiler动态编译
 43  * ->JavaCompiler compiler=ToolProvider.getSystemJavaCompiler();
 44  *   int result=compiler.run(null,null,null,sourceFile);
 45  *   第一个参数:为java编译器提供参数  InputStream
 46  *   第二个参数:得到java编译器的输出信息 OutputStream
 47  *   第三个参数:接收编译器的错误信息
 48  *   第四个参数:可变参数(为String数组)能传入一个或多个java源文件
 49  *   返回值:1表示编译成功,0表示编译失败
 50  *
 51  * 三.动态执行JavaScript代码:
 52  * Java脚本引擎:
 53  *  使得java的应用程序可以通过一套固定的接口与各种脚本引擎交互,从而达到在Java平台上调用各种脚本语言的目的。
 54  *  可以把一些复杂异变的业务逻辑交给脚本语言处理,大大提高开发效率
 55  *  (1)获得脚本引擎对象:
 56  *  ScriptEngineManager sem=new ScriptEngineManager();
 57  *  ScriptEngine engine=sem.getEngineByName("javascript");
 58  *  功能:
 59  * (1)获取脚本程序输入,通过脚本引擎运行脚本并返回运行结果,这是最核心的接口。 JS使用了Rhino
 60  * (2)通过脚本引擎的运行上下文在脚本和Java平台间交换数据。
 61  * (3)通过Java应用程序调用脚本函数。
 62  *
 63  * 四.动态字节码操作:
 64  * 功能:动态生成新的类,动态改变某个类的结构(增加,删除,修改 新的属性/方法 )
 65  * 优势:比反射的开销小,性能高,Javassist性能高于反射,低于ASM
 66  * 常见的字节码操作类库:
 67  * BCEL:在实际的JVM指令层次上进行操作,拥有丰富的JVM指令级支持
 68  * ASM:是一个轻量级java字节码操作框架,直接涉及到JVM底层的操作和指令
 69  * CGLIB:是一个强大的,高性能,高质量的code生成类库,基于ASM实现
 70  * Javassist:是一个开源的分析,编辑和创建字节码的类库,性能较ASM差,较cglib差不多,使用简单
 71  * ->最外层的API和JAVA反射包中的API颇为相似:
 72  * 主要由CtClass,CtMethod以及CtField几个类组成,
 73  * 用以执行和JDK反射API中java.lang.Class,java.lang.reflect.Method
 74  * 以及java.lang.reflect.Method.Field相同的操作
 75  *
 76  * 局限性:
 77  * 不支持泛型,枚举,不支持注释修改,但可以通过底层的javassist类解决
 78  * 不支持数组的初始化,内部类和匿名类,不支持continue,break语句还有部分继承关系
 79  *
 80  */
 81
 82 @SuppressWarnings("all")
 83 public class Reflect {
 84
 85     public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ScriptException {
 86
 87         try {
 88             getInfoByReflect();
 89             useConstructorByReflect();
 90             useReflectMethod();
 91             getTypeAll();
 92             /*testComplier();*/
 93             scriptEngine();
 94         } catch (ClassNotFoundException e) {
 95             e.printStackTrace();
 96         }
 97
 98     }
 99
100     //通过反射获取Class对象里面对应类的属性
101     public static void getInfoByReflect() throws ClassNotFoundException {
102         //获取Student类的Class对象
103         Class c=Class.forName("com.reflection.Student");
104         //通过该Class对象获取该类的具体名字(包含包名)及类名
105         String realName=c.getName();
106         String name=c.getSimpleName();
107         System.out.println("具体名字:"+realName+" 类名:"+name);
108
109         //获取类的属性
110         //Field[] field=c.getFields();//只能获取public的属性
111         Field[] fields=c.getDeclaredFields();
112         //获取所有属性
113         for(Field f:fields) {
114             System.out.println("属性:"+f);
115         }
116         /*获取类所有的方法
117         PS:如果方法有参,则必须参数类型对应的Class对象
118         Method m1=c.getDeclaredMethod("getName", null);
119         Method m2=c.getDeclaredMethod("setName", String.class);*/
120         Method[] methods=c.getMethods();
121         for(Method m:methods) {
122             System.out.println("方法:"+m);
123         }
124         //获取类所有的构造器
125         Constructor[] constructors=    c.getConstructors();
126         for(Constructor con:constructors) {
127             System.out.println("构造器:"+con);
128         }
129     }
130
131     //通过反射调用构造方法,构造对象,创建记录并将其放入集合中,然后打印出来
132     public static void useConstructorByReflect() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
133         Class c=Class.forName("com.reflection.Student");
134         Constructor<Student> cr=c.getConstructor(int.class,String.class,String.class);
135         Student s1=cr.newInstance(123,"张三","软件一班");
136         Student s2=cr.newInstance(456,"李四","软件二班");
137         List<Student> list=new ArrayList<Student>();
138         list.add(s1);
139         list.add(s2);
140         System.out.println("编号:"+list.get(0).getId()+" 姓名:"+list.get(0).getName()+" 班级:"+list.get(0).getCname());
141         System.out.println("编号:"+list.get(1).getId()+" 姓名:"+list.get(1).getName()+" 班级:"+list.get(1).getCname());
142     }
143
144     //利用对象里面的方法来对 Student实体类进行初始化数据操作
145     public static void useReflectMethod() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
146         Class c2=Class.forName("com.reflection.Student");
147         Student s3=(Student)c2.newInstance();
148         //先获取Class对象里面的方法
149         Method m2=c2.getDeclaredMethod("setName", String.class);
150         //使用该方法
151         m2.invoke(s3, "王五");
152         System.out.println("方法实现后获取值为:"+s3.getName());
153     }
154
155     //对包含泛型的方法进行处理
156     public static void getTypeAll() throws NoSuchMethodException, SecurityException {
157         //获取指定方法泛型参数信息
158         Method m3=Reflect.class.getMethod("test01",Map.class,List.class);
159         Type[] types=m3.getGenericParameterTypes();
160         for(Type t:types) {
161             System.out.println("#"+t);
162             if (t instanceof ParameterizedType) {
163                 Type[] generalType=((ParameterizedType) t).getActualTypeArguments();
164                 for(Type gtype:generalType) {
165                     System.out.println("泛型类型为:"+gtype);
166                 }
167             }
168         }
169         //获取指定方法泛型返回值信息
170         Method m4=Reflect.class.getMethod("test02", null);
171         Type returnType=m4.getGenericReturnType();
172         if(returnType instanceof ParameterizedType) {
173             Type[] generalType=((ParameterizedType) returnType).getActualTypeArguments();
174             for(Type gtype:generalType) {
175                 System.out.println("返回值泛型类型为:"+gtype);
176             }
177         }
178     }
179
180     //动态编译方法实现
181     public static void testComplier() {
182         JavaCompiler compiler=ToolProvider.getSystemJavaCompiler();
183         int result=compiler.run(null,null,null,"");
184         System.out.println(result==0?"编译成功":"编译失败");
185     }
186
187     //构造一个带泛型参数的方法
188     public void test01(Map<String,Student> map,List<Student> stu){
189         System.out.println("测试");
190     }
191     //构造一个带泛型返回值的方法
192     public Map<String,Student> test02(){
193         return null;
194     }
195
196     //脚本引擎简单使用
197     public static void scriptEngine() throws ScriptException {
198         //获取脚本引擎对象
199         ScriptEngineManager sem=new ScriptEngineManager();
200         ScriptEngine engine=sem.getEngineByName("javascript");
201         //定义变量存储到脚本引擎的上下文中
202         engine.put("msg", "我很喜欢敲代码!");
203         System.out.println("获取到的信息为:"+engine.get("msg"));
204
205         String str="var user= {name:'张三',age:18};";
206         str +="print('用户名:'+user.name);";
207         //执行脚本
208         engine.eval(str);
209         //利用脚本引擎执行javascript的函数
210         String st="function time() { var a=10,b=a*10;print('最终结果为:'+b);}; time();";
211         engine.eval(st);
212     }
213 }

效果截图:

ps:文章待完善,如存在不正之处欢迎大佬指出。

转载于:https://www.cnblogs.com/weekstart/p/10838717.html

java-java动态性之反射,动态编译,动态执行js及动态字节码操作相关推荐

  1. 菜鸟学习笔记:Java提升篇12(Java动态性2——动态编译、javassist字节码操作)

    菜鸟学习笔记:Java提升篇12(Java动态性2--动态编译.javassist字节码操作) Java的动态编译 通过脚本引擎执行代码 Java字节码操作 JAVAssist的简单使用 常用API ...

  2. 注解、反射、动态编译、字节码操作

    注解.反射.动态编译.字节码操作 前言:本篇博客将介绍Java中注解的定义.使用以及反射对Java动态性的支持和Java字节码操作,通过本篇内容,读者将对Java知识有更加深刻的理解,同时为后面And ...

  3. 【Java字节码操作】JavaAssist的使用方式,代码示例

    BCEL和ASM效率最高,因为他们基于虚拟机的指令操作,但是这两个最难学. JavaAssist 库,官网介绍如下: 让Java操作字节码更加简单,可以用Java语言直接编辑字节码 提供两种层次的AP ...

  4. asm字节码操作 方法的动态修改增加

    asm 4.0 版本 http://forge.ow2.org/plugins/scmsvn/index.php?group_id=23 asm是java的字节码操作框架,可以动态查看类的信息,动态修 ...

  5. java动态编译无法导包_java动态编译整个项目,解决jar包找不到问题.doc

    java动态编译整个项目,解决jar包找不到问题.doc 还剩 8页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,喜欢就下载吧,价低环保! 内容要点: 64. } 65. 66. /*** ...

  6. 如何用C#动态编译、执行代码

    在开始之前,先熟悉几个类及部分属性.方法:CSharpCodeProvider.ICodeCompiler.CompilerParameters.CompilerResults.Assembly. 一 ...

  7. 一个java源文件中可以声明多少个class与编译后会生成多少个字节码文件

    在一个java源文件中可以声明多个class. 但是,只能最多有一个类声明为public的. 而且要求声明为public的类的类名必须与源文件名相同. 编译的过程 编译以后,会生成一个或多个字节码文件 ...

  8. 使用Roslyn动态编译和执行

    1. 安装nuget package 2.使用Roslyn 动态执行 var engine = new Roslyn.Scripting.CSharp.ScriptEngine();engine.Cr ...

  9. 深入解析Java字节码和字节码操作类库ASM源码解析

    导语 在非黑即白的静态编译语言和动态脚本语言的分类方法中,java的立场显得很尴尬.首先java是静态强类型语言,所以java源代码是需要编译的.但是javac编译后的产出物并不是和传统的编译语言一样 ...

  10. 动态星空效果html,JS实现动态星空背景效果

    本文实例为大家分享了JS实现动态星空背景的具体代码,供大家参考,具体内容如下 这里我截取的是一个图片,实际上是会动的.废话不多说,上代码. HTML: CSS: /*css reset */ body ...

最新文章

  1. 浏览器tab关闭事件_Python--使用Pyqt5实现简易浏览器(最新版本测试过)
  2. HTML语言基础.上
  3. 深入浅出WPF(2)——解剖最简单的GUI程序
  4. Chapter09-内核模式下的线程同步之事件内核对象
  5. easyui datebox时间控件如何只显示年月
  6. vue--配套axios用法
  7. Java使用IntelliJ IDEA创建控制台程序并通过JDBC连接到数据库
  8. vue.js基础知识篇(1):简介、数据绑定
  9. 关于 Eureka 2.x,别再人云亦云了!
  10. springBean生命周期
  11. 困了累了到底喝啥?浅谈饮料品牌如何进行推广策略定位
  12. 信号与频谱之正弦信号和复信号
  13. Java 读取jpeg图片 Unsupported Image Type 异常
  14. 学会这几个.你就能成为bat脚本小子了...(转来看看的)
  15. weblogic 14c 的下载和安装
  16. MySQL的下载与安装教程--超详细
  17. 世纪佳缘钓鱼白帽子,互联网安全的边界如何界定?
  18. python ppt 图片_python ppt 转 pdf 图片
  19. c语言mon什么意思,c'mon是什么意思啊 – 手机爱问
  20. geoserver发布TIF格式瓦片地图

热门文章

  1. Adopt Open JDK官方文档(八)OpenJDK 项目介绍
  2. FLC-Regular Grammar
  3. iOS 开发笔记-plist使用
  4. 溜达列表的鼠标HOVER变色
  5. 两年前,梦开始的地方.
  6. 移植oprofile到海思
  7. 基于M6097 switch的STP协议调试方法
  8. java开发web应用开发,Java Web应用开发概述
  9. mysql怎么判断多行数据日期是否连续_MySQL学习笔记(一)
  10. SO_REUSEADDR 套接字选项应用实例