天天看点

Java反射

<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对象就像一面镜子,透过这个镜子看到类的结构

Java反射

那么,如何得到这个Class对象呢?以下可否

答案是不行的,因为Class的构造函数定义为私有的,只有JVM可以访问

Class对象获取的三种方式

举例

<a></a>

输出

本文以Student类为例:

接口

Java反射
Java反射

以下具体介绍下具体的用法

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&lt;java.lang.String, com.example.refs.Student&gt;</code>

<code>泛型类型:class java.lang.String</code>

<code>泛型类型:class com.example.refs.Student</code>

<code>#:java.util.List&lt;com.example.refs.Student&gt;</code>

<code>Returntypejava.util.Map&lt;java.lang.Integer, com.example.refs.Student&gt;</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,如需转载请自行联系原作者

下一篇: Java集合

继续阅读