<b>阅读目录</b>
<a href="http://www.cnblogs.com/kaituorensheng/p/7398069.html#_label0">1. 介绍</a>
<a href="http://www.cnblogs.com/kaituorensheng/p/7398069.html#_label1">2. Java反射相关操作</a>
<a href="http://www.cnblogs.com/kaituorensheng/p/7398069.html#_label2">3. 分析</a>
反射是一种能够在程序运行时动态访问、修改某个类中任意属性和方法的机制。
具体:
对于任意一个类,都能够知道这个类的所有属性和方法
对于任意一个对象,都能够调用它的任意一个方法和属性
在运行时,当加载完类之后,JVM在堆内存中会自动产生一个Class类型的对象,这个对象包含了完整的类的结构信息
这个Class对象就像一面镜子,透过这个镜子看到类的结构

那么,如何得到这个Class对象呢?以下可否
答案是不行的,因为Class的构造函数定义为私有的,只有JVM可以访问
Class对象获取的三种方式
举例
<a></a>
输出
本文以Student类为例:
接口
类
以下具体介绍下具体的用法
2.1 类名称、包名
1
2
3
<code>getSimpleName:Student</code>
<code>getName:com.example.refs.Student</code>
<code>getPackage:package: com.example.refs</code>
2.2 方法
结果
4
5
6
7
8
9
10
11
12
13
14
15
<code>getMethods: </code><code>public</code> <code>void</code> <code>com.example.refs.Student.read()</code>
<code>getMethods: </code><code>public</code> <code>void</code> <code>com.example.refs.Student.setId(</code><code>int</code><code>)</code>
<code>getMethods: </code><code>public</code> <code>final </code><code>void</code> <code>java.lang.Object.wait() throws java.lang.InterruptedException</code>
<code>getMethods: </code><code>public</code> <code>final </code><code>void</code> <code>java.lang.Object.wait(</code><code>long</code><code>,</code><code>int</code><code>) throws java.lang.InterruptedException</code>
<code>getMethods: </code><code>public</code> <code>final native </code><code>void</code> <code>java.lang.Object.wait(</code><code>long</code><code>) throws java.lang.InterruptedException</code>
<code>getMethods: </code><code>public</code> <code>boolean java.lang.Object.</code><code>equals</code><code>(java.lang.Object)</code>
<code>getMethods: </code><code>public</code> <code>java.lang.String java.lang.Object.toString()</code>
<code>getMethods: </code><code>public</code> <code>native </code><code>int</code> <code>java.lang.Object.hashCode()</code>
<code>getMethods: </code><code>public</code> <code>final native java.lang.Class java.lang.Object.getClass()</code>
<code>getMethods: </code><code>public</code> <code>final native </code><code>void</code> <code>java.lang.Object.notify()</code>
<code>getMethods: </code><code>public</code> <code>final native </code><code>void</code> <code>java.lang.Object.notifyAll()</code>
<code>getDeclaredMethods: </code><code>public</code> <code>void</code> <code>com.example.refs.Student.read()</code>
<code>getDeclaredMethods: </code><code>private</code> <code>int</code> <code>com.example.refs.Student.getId()</code>
<code>getDeclaredMethods: </code><code>public</code> <code>void</code> <code>com.example.refs.Student.setId(</code><code>int</code><code>) </code>
指定方法
异常
原因:setId为私有方法,利用反射时会进行安全检查,用setAccessible(true)不进行安全检查,可以直接对调用私有方法、修改私有变量
2.3 构造函数
2.4 成员变量
getDeclaredFields()获得某个类的所有申明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
getFields()获得某个类的所有的公共(public)的字段,包括父类。
2.5 修饰符
2.6 父类
2.7 接口
2.8 创建对象实例
举例用2种方法创建
<code>com.example.refs.Student@72ea2f77</code>
<code>com.example.refs.Student@33c7353a</code>
<code>com.example.refs.Student@681a9515</code>
2.9 注解
自定义一个注解
注:RetentionPolicy.RUNTIME 这个表示运行期注解,这样在反射的时候才能取到
2.10 泛型
参数类型、返回值类型举例
<code>#:java.util.Map<java.lang.String, com.example.refs.Student></code>
<code>泛型类型:class java.lang.String</code>
<code>泛型类型:class com.example.refs.Student</code>
<code>#:java.util.List<com.example.refs.Student></code>
<code>Returntypejava.util.Map<java.lang.Integer, com.example.refs.Student></code>
<code>返回值,泛型类型:class java.lang.Integer</code>
<code>返回值,泛型类型:class com.example.refs.Student</code>
2.11 数组
<code>array[0]:123</code>
<code>array[1]:124</code>
<code>array[2]:125</code>
<code>intArray是否是数组类型:</code><code>true</code>
<code>intArray成员类型:int </code>
3.1 使用场景
操作因访问权限限制的属性和方法
实现自定义注解
动态加载第三方jar包
按需加载类,节省编译和初始化APK的时间
3.2 优缺点
优点:灵活、自由度高:不受类的访问权限限制
缺点
性能问题:通过反射访问、修改类的属性和方法时会远慢于直接操作,但性能问题的严重程度取决于在程序中是如何使用反射的。如果使用得很少,不是很频繁,性能将不是问题
安全性问题:反射可以随意访问和修改类的所有状态和行为,破坏了类的封装性,如果不熟悉被反射类的实现原理,随意修改可能导致潜在的逻辑问题
兼容性问题:因为反射会涉及到直接访问类的方法名和实例名,不同版本的API如果有变动,反射时找不到对应的属性和方法时会报异常
3.3 说明
通过反射访问方法比实例慢很多
有用到反射的类不能被混淆
反射存在性能问题,但使用不频繁、按需使用时,对程序性能影响并不大
反射存在安全性问题,因为可以随意修改类的所有状态和行为(包括private方法和实例)
使用反射访问Android的API时需要注意因为不同API版本导致的兼容性问题
3.4 性能对比
不使用反射、启用安全检查、启用安全检查进行对比
结果对比
差异
耗时(ms)
没用反射
952
取消安全检查
4283
启用安全检查
14892
本文转自jihite博客园博客,原文链接:http://www.cnblogs.com/kaituorensheng/p/7398069.html,如需转载请自行联系原作者