反射的用法:
https://www.jianshu.com/p/9be58ee20dee
https://blog.csdn.net/huangliniqng/article/details/88554510
Java中编译类型有两种:
- 静态编译:编译时确定类型
- 动态编译:运行时确定类型
Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时,透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public、static等)、superclass(例如Object)、实现的interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。
Java程序可以加载一个运行时才得知名称的class,获取其完整构造,并生成其对象实体、或对其fields设值、或唤起其methods。
实现Java反射机制的类都位于java.lang.reflect包中:
- Class类:代表一个类
- Field类:代表类的成员变量(类的属性)
- Method类:代表类的方法
- Constructor类:代表类的构造方法
- Array类:提供了动态创建数组,以及访问数组的元素的静态方法
首先JVM会启动,你的代码会编译成.class文件,然后被类加载器加载进jvm的内存中,你的类Object加载到方法区中,创建的Object类的class对象到堆中,注意这个不是new出来的对象,而是类的类型对象,每个类只有一个class对象,作为方法区类的数据结构的接口。jvm创建对象前,先检查类是否加载,寻找类对应的class对象,若加载好,则为你的对象分配内存,初始化也就是代码:new Object()。
为什么要讲这个呢?因为要理解反射必须知道它在什么场景下使用。
上面的程序对象是自己new的,程序相当于写死了给jvm去跑。假如一个服务器上突然遇到某个请求要用到某个类,但没加载进jvm,是不是要停下来自己写段代码,new一下,启动一下服务器,(脑残)!
反射是什么呢?当我们的程序在运行时,需要动态的加载一些类,这些类可能之前用不到,所以不用加载到jvm,而是在运行时根据需要才加载。
举个例子我们的项目底层有时是用mysql,有时用oracle,需要动态地根据实际情况加载驱动类,这个时候反射就有用了,假设 com.java.dbtest.myqlConnection,com.java.dbtest.oracleConnection这两个类我们要用,这时候我们的程序就写得比较动态化,通过Class tc = Class.forName("com.java.dbtest.TestConnection");
通过类的全类名,让jvm在服务器中找到并加载这个类,而如果是oracle则传入的参数就变成另一个了。这时候就可以看到反射的好处了,这个动态性就体现出java的特性了!
新建一个配置文件,里面填mysql或oracle,然后代码中取得配置文件的字符串,if是 mysql就 conn =new MysqlConnection() 是oracle就 conn =new OracleConnection,然后。最重要的是。你要停掉生产环境,重新把java代码用javac编译一遍,再把编译后的class文件把生产环境给起起来。
反射:考虑到有时会切换数据库,写成配置文件,然后用Class.forName(str)什么的来new 数据库驱动,更改数据库时就仅需更改配置文件,不需要重新编译代码,但还需要重新启动生产环境。这里用反射和不用反射的区别在于,是否要重新编译一遍。
举多个例子,大家如果接触过spring,会发现当你配置各种各样的bean时,是以配置文件的形式配置的,你需要用到哪些bean就配哪些,spring容器就会根据你的需求去动态加载,你的程序就能健壮地运行。