Java反射的好处
反射的好处
我们在第⼀次接触反射的时候,总会有个很⼤的疑问,反射看起来好⿇烦啊,各种,他究竟有什么好处,能⽤来做什么呢?
我们先来看⼀下《编程思想》这本书中是怎么说的.
RTTI和反射之间真正的区别只在于,对RTTI来说,编译器在在编译时打开和检查.class⽂件.(换句话说,我们可以⽤"普通"⽅式调⽤对象的所有⽅法).对于反射机制来说,.class⽂件在编译时是不可获取的,所以在运⾏时打开和检查.class⽂件。 --《编程思想》
这段话看起来很叼的样⼦,有点云⾥雾⾥的,⾸先RTTI的意思就是以普通的⽅式来创建对象,调⽤⽅法,就是我们常⽤的new关键字。这段话的意思简化版就是:编译器将.java⽂件编译成.class⽂件之后,普通⽅式创建的对象就不能再变了,我只能选择是运⾏还是不运⾏这
个.class⽂件。是不是感觉很僵硬,假如现在我有个写好的程序已经放在了服务器上,每天供⼈家来访问,这时候Mysql数据库宕掉了,改⽤Oracle,这时候该怎么怎么办呢?假如没有反射的话,我们是不是得修改代码,将Mysql驱动改为Oracle驱动,重新编译运⾏,再放到服务器上。是不是很⿇烦,还影响⽤
户的访问。
假如我们使⽤反射Class.forName()来加载驱动,只需要修改配置⽂件就可以动态加载这个类,Class.forName()⽣成的结果在编译时是不可知的,只有在运⾏的时候才能加载这个类,换句话说,此时我们是不需要将程序停下来,只需要修改配置⽂件⾥⾯的信息就可以了。这样当有⽤户在浏览器访问这个⽹站时,都不会感觉到服务器程序程序发⽣了变化。
所以在《Mybatis技术原理与实战》是这么说反射的好处的。
配置性⼤⼤提⾼,如同Spring IOC容器,给很多配置设置参数,使得java应⽤程序能够顺利跑起来,⼤⼤提⾼了Java的灵活性和可配置性,降低模块间的耦合。--《Mybatis技术原理与实战》
相应的实例
Eclipse的代码⾃动补全就是利⽤了反射原理动态的加载要展⽰的⽅法,因为反射会影响性能,所以开了⾃动补全刚开始的时候会卡⼀下,主要还是我电脑性能不⾏。
反射的进阶
在JDK动态代理中可以利⽤反射直接获取到接⼝的⽅法来执⾏,从⽽可以将代理类要处理的代码抽象出来形成统⼀的接⼝。
Java的反射中Class.forName和ClassLoader的区别
ClassLoader:
ClassLoader就是遵循双亲委派模型最终调⽤启动类加载器的类加载器,实现的功能是“通过⼀个类的全限定名来获取描述此类的⼆进制字节流”,获取到⼆进制流后放到JVM中。
例如SystemClassLoader().loadClass("st.ClassForName");是不会初始化类的。
Class.forName():
Class.forName()⽅法实际上也是调⽤的CLassLoader来实现的。
Class.forName(String name, boolean initialize,ClassLoader loader)⽅法来⼿动选择在加载类的时候是否要对类进⾏初始化。
应⽤场景:
1. 在我们熟悉的Spring框架中的IOC的实现就是使⽤的ClassLoader。
2. 使⽤JDBC时通常是使⽤Class.forName()⽅法来加载数据库连接驱动。这是因为在JDBC规范中明确要求Driver(数据库驱动)类必须向DriverManager注册⾃⼰
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
// Register ourselves with the DriverManager
static {
try {
java.isterDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
java反射的作用及应用场景}
public Driver() throws SQLException {
// Required for Class.forName().newInstance()
}
}
Class.forName()会初始化类,所以⾃动加载static代码段,从⽽注册⾃⼰。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论