Java反射和ReflectionUtils
复习了佟老师和毕老师的视频,也阅读了一些写的很棒的博客,整理一下Java中关于反射的笔记。包括一个ReflectionUtils。
什么是反射
反射,即Reflect,使得程序在运行时能够像照镜子一样获得自身的一些信息。比如一个类中可以有那些方法,那些字段,而不需要知道源代码。
Java是一门静态语言,即在编译是就确定了类型,换句话说程序在运行时是不能修改自身的。这和Python或者JavaScript不一样,后者是动态语言,可以在程序运行时动态的进行修改。
JavaScript动态特性的例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21window.onload = function() {
var person = new Object();
person.name = "Jack";
person.getName = function() {
return this.name;
}
console.log(person.getName());
person.getName = function() {
return "Mr." + this.name;
}
console.log(person.getName());
person.getName = undefined;
console.log(person.getName());
}
输出结果:
jack
Mr.jack
Uncaught TypeError: person.getName is not a function
反射的作用
一个经常被提到的例子就是JBDC中DriverManager使用Class.forName()来加载JDBC的驱动。1
2
3
4
5
6
7
8
9for (String aDriver : driversList) {
try {
println("DriverManager.Initialize: loading " + aDriver);
Class.forName(aDriver, true,
ClassLoader.getSystemClassLoader());
} catch (Exception ex) {
println("DriverManager.Initialize: load failed: " + ex);
}
}
DriverManager只需要根据预先设好的JDBC驱动类的名字就可以加载并生成驱动实例。比如设置“java.mysql.jdbc.Driver”就可以加载好MySQL数据库的驱动,设置“oracle.jdbc.driver.OracleDriver”就可以加载好Oracle数据库的驱动。
在之后的学习中,也了解到比如Struts、Spring、Hibernate等诸多框架中都是使用了反射。比如在配置文件中写上Bean实例的全名,Spring就可以根据这个全名利用反射自动的生成实例放在IOC容器中。
另一方面,反射能够有效降低类之间的耦合,一个大型的框架或者软件中,需要不断的后期去修改升级。如果修改或增加了功能,每次都重新发布整体新包让用户重新安装也不大方便。为此,可以使用很多方法去将程序模块化,降低耦合。这里举反射的例子,还是上面的JDBC的驱动,比如一开始使用版本是1.0,后来升级到了1.1,只需要替换相应的jar包或者再修改下配置文件就行,而不需要修改其他部分的代码。
此外,使用反射可以生成一些模板方法,避免容易犯低级错误的重复劳动,比如下面两对SQL语句。
1 | INSERT INTO USER(ID,NAME,AGE) VALUES (123456,'jack',20); |
观察发现基本语法写法一致,只是内容不一样而已。使用反射原理,传入User和Department两个对象就可以生成这两种SQL语句(Hibernate的原理之一)。
可以使用getMethods()方法获得所有可访问的方法,getFields获得所有可访问的字段,然后再获得这个由方法和字段获得对象中存储的字段值(value),最终就可以拼凑出SQL来。
反射工具类
这个是反射工具类,基于佟老师的讲课视频,加以整理。
包括:
1、获得类中某个名为xxx的方法
2、执行类或对象中某个名为xxx的方法
3、获得类中某个名为yyy的字段(属性)
4、设置对象中名为yyy的字段(属性)的值
5、获得类中某个构造方法
6、通过类中的构造方法和参数创建类实例
7、获得类、方法、字段的某个注解
8、获得某个类后者其父类的泛型参数类型
下面贴上源码,完整的包括测试代码在这里可以下载:
1 | package com.chain.javase.reflect.utils; |
编程就像练功一样,这只是一个简单的工具类。像反射,注解,泛型等Java中哪怕是最基本的知识点,也需要不断的去阅读书籍和源码,才能体会到它们的更牛的用法。