1. 了解Java中的反射
1.1 什么是Java的反射
Java反射是可以让我们在运行时获取类的函数、字段、父类、接口等Class内部信息的机制。通过反射还可以让我们在运行期实例化对象,调用方法,通过调用get/set方法获取变量的值,即使方法或字段是私有的的也可以通过反射的形式调用,这种“看透class”的能力被称为内省,这种能力在框架开发中尤为重要。
有些情况下,我们要使用的类在运行时才会确定,这个时候我们不能在编译期就使用它,因此只能通过反射的形式来使用在运行时才存在的类(该类符合某种特定的规范,例如JDBC),这是反射用得比较多的场景。
还有一个比较常见的场景就是编译时我们对于类的内部信息不可知,必须得到运行时才能获取类的具体信息。比如ORM框架,在运行时才能够获取类中的各个字段,然后通过反射的形式获取其字段名和值,存入数据库。这也是反射比较经典应用场景之一。
1.2 Class类
那么既然反射是操作Class信息的,Class又是什么呢?
当我们编写完一个Java项目之后,所有的Java文件都会被编译成一个.class文件,这些Class对象承载了这个类型的父类、接口、构造函数、方法、字段等原始信息,这些class文件在程序运行时会被ClassLoader加载到虚拟机中。当一个类被加载以后,Java虚拟机就会在内存中自动产生一个Class对象。我们通过new的形式创建对象实际上就是通过这些Class来创建,只是这个过程对于我们是不透明的而已。
下面的章节中我们会为大家演示反射的一些常用api,从代码的角度理解反射。
2. 反射Class以及构造对象
2.1 获取Class对象
在你想检查一个类的信息之前,你首先需要获取类的Class对象。Java中的所有类型包括基本类型,即使是数组都有与之关联的Class类的对象。如果你在编译期知道一个类的名字的话,那么你可以使用如下的方式获取一个类的Class对象。
<code class=" hljs vbnet"><span class="hljs-keyword">Class</span><?> myObjectClass = MyObject.<span class="hljs-keyword">class</span>;</code>
如果你已经得到了某个对象,但是你想获取这个对象的Class对象,那么你可以通过下面的方法得到:
<code class=" hljs vbnet"> Student <span class="hljs-keyword">me</span> = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">"mr.simple"</span>); <span class="hljs-keyword">Class</span><?> clazz = <span class="hljs-keyword">me</span>.getClass();</code>
如果你在编译期获取不到目标类型,但是你知道它的完整类路径,那么你可以通过如下的形式来获取Class对象:
<code class=" hljs vbnet"><span class="hljs-keyword">Class</span><?> myObjectClass = <span class="hljs-keyword">Class</span>.forName(<span class="hljs-string">"com.simple.User"</span>);</code>
在使用Class.forName()方法时,你必须提供一个类的全名,这个全名包括类所在的包的名字。例如User类位于com.simple包,那么他的完整类路径就是com.simple.User。
如果在调用Class.forName()方法时,没有在编译路径下(classpath)找到对应的类,那么将会抛出ClassNotFoundException。
接口说明
<code class=" hljs delphi"><span class="hljs-comment">// 加载指定的Class对象,参数1为要加载的类的完整路径,例如"com.simple.Student". ( 常用方式 )</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">Class</span><?> forName (<span class="hljs-keyword">String</span> className) <span class="hljs-comment">// 加载指定的Class对象,参数1为要加载的类的完整路径,例如"com.simple.Student";</span> <span class="hljs-comment">// 参数2为是否要初始化该Class对象,参数3为指定加载该类的ClassLoader.</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">Class</span><?> forName (<span class="hljs-keyword">String</span> className, boolean shouldInitialize, ClassLoader classLoader) </code>
2.2 通过Class对象构造目标类型的对象
一旦你拿到Class对象之后,你就可以为所欲为了!它就像潘多拉的魔盒,但更多的时候当你善用它的时候它就是神兵利器,当你心怀鬼胎之时它就会变成恶魔。但获取Class对象只是第一步,我们需要在执行那些强大的行为之前通过Class对象构造出该类型的对象,然后才能通过该对象释放它的能量。
我们知道,在java中药构造对象,必须通过该类的构造函数,那么其实反射也是一样一样的。但是它们确实有区别的,通过反射构造对象,我们首先要获取类的Constructor(构造器)对象,然后通过Constructor来创建目标类的对象。还是直接上代码的。
<code class=" hljs cs"> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> classForName() { <span class="hljs-keyword">try</span> { <span class="hljs-comment">// 获取Class对象</span> Class<?> clz = Class.forName(<span class="hljs-string">"org.java.advance.reflect.Student"</span>); <span class="hljs-comment">// 通过Class对象获取Constructor,Student的构造函数有一个字符串参数,</span> <span class="hljs-comment">// 因此这里需要传递参数的类型 ( Student类见后面的代码 )</span> Constructor<?> constructor = clz.getConstructor(String.class); <span class="hljs-comment">// 通过Constructor来创建Student对象</span> Object obj = constructor.newInstance(<span class="hljs-string">"mr.simple"</span>); System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">" obj : "</span> + obj.toString()); } <span class="hljs-keyword">catch</span> (Exception e) { e.printStackTrace(); } }</code>
通过上述代码,我们就可以在运行时通过完整的类名来构建对象。
获取构造函数接口
<code class=" hljs delphi"><span class="hljs-comment">// 获取一个公有的构造函数,参数为可变参数,如果构造函数有参数,那么需要将参数的类型传递给getConstructor方法</span> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">Constructor</span><<span class="hljs-title">T</span>> <span class="hljs-title">getConstructor</span> <span class="hljs-params">(<span class="hljs-keyword">Class</span>...<?> parameterTypes)</span> // 获取目标类所有的公有构造函数 <span class="hljs-title">public</span> <span class="hljs-title">Constructor</span>[]<?> <span class="hljs-title">getConstructors</span> <span class="hljs-params">()</span> </span></code>
由于后面还会用到Student以及相关的类,我们在这里就先给出它们的代码吧。
Person.java
<code class=" hljs cs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> Person { String mName; <span class="hljs-keyword">public</span> <span class="hljs-title">Person</span>(String aName) { mName = aName; } <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sayHello</span>(String friendName) { System.<span class="hljs-keyword">out</span>.println(mName + <span class="hljs-string">" say hello to "</span> + friendName); } <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">showMyName</span>() { System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"My name is "</span> + mName); } <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">breathe</span>() { System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">" take breathe "</span>); } }</code>
Student.java
<code class=" hljs java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Student</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Person</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Examination</span> {</span> <span class="hljs-comment">// 年级</span> <span class="hljs-keyword">int</span> mGrade; <span class="hljs-keyword">public</span> <span class="hljs-title">Student</span>(String aName) { <span class="hljs-keyword">super</span>(aName); } <span class="hljs-keyword">public</span> <span class="hljs-title">Student</span>(<span class="hljs-keyword">int</span> grade, String aName) { <span class="hljs-keyword">super</span>(aName); mGrade = grade; } <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">learn</span>(String course) { System.out.println(mName + <span class="hljs-string">" learn "</span> + course); } <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">takeAnExamination</span>() { System.out.println(<span class="hljs-string">" takeAnExamination "</span>); } <span class="hljs-keyword">public</span> String <span class="hljs-title">toString</span>() { <span class="hljs-keyword">return</span> <span class="hljs-string">" Student : "</span> + mName; }</code>
Breathe.java
<code class=" hljs cs"><span class="hljs-comment">// 呼吸接口</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> Breathe { <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">breathe</span>(); }</code>
Examination.java
<code class=" hljs cs"><span class="hljs-comment">// 考试接口</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> Examination { <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">takeAnExamination</span>(); }</code>
3 反射获取类中函数
3.1 获取当前类中定义的方法
要获取当前类中定义的所有方法可以通过Class中的getDeclaredMethods函数,它会获取到当前类中的public、default、protected、private的所有方法。而getDeclaredMethods则是获取某个指定的方法。代码示例如下 :
<code class=" hljs avrasm"> private static void showDeclaredMethods() { Student student = new Student(<span class="hljs-string">"mr.simple"</span>)<span class="hljs-comment">;</span> Method[] methods = student<span class="hljs-preprocessor">.getClass</span>()<span class="hljs-preprocessor">.getDeclaredMethods</span>()<span class="hljs-comment">;</span> for (Method method : methods) { System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"declared method name : "</span> + method<span class="hljs-preprocessor">.getName</span>())<span class="hljs-comment">;</span> } try { Method learnMethod = student<span class="hljs-preprocessor">.getClass</span>()<span class="hljs-preprocessor">.getDeclaredMethod</span>(<span class="hljs-string">"learn"</span>, String<span class="hljs-preprocessor">.class</span>)<span class="hljs-comment">;</span> // 获取方法的参数类型列表 Class<?>[] paramClasses = learnMethod<span class="hljs-preprocessor">.getParameterTypes</span>() <span class="hljs-comment">;</span> for (Class<?> class1 : paramClasses) { System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"learn 方法的参数类型 : "</span> + class1<span class="hljs-preprocessor">.getName</span>())<span class="hljs-comment">;</span> } // 是否是private函数,字段是否是private也可以使用这种方式判断 System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(learnMethod<span class="hljs-preprocessor">.getName</span>() + <span class="hljs-string">" is private "</span> + Modifier<span class="hljs-preprocessor">.isPrivate</span>(learnMethod<span class="hljs-preprocessor">.getModifiers</span>()))<span class="hljs-comment">;</span> learnMethod<span class="hljs-preprocessor">.invoke</span>(student, <span class="hljs-string">"java ---> "</span>)<span class="hljs-comment">;</span> } catch (Exception e) { e<span class="hljs-preprocessor">.printStackTrace</span>()<span class="hljs-comment">;</span> } }</code>
3.2 获取当前类、父类中定义的公有方法
要获取当前类以及父类中的所有public方法可以通过Class中的getMethods函数,而getMethod则是获取某个指定的方法。代码示例如下 :
<code class=" hljs cs"> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">showMethods</span>() { Student student = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">"mr.simple"</span>); <span class="hljs-comment">// 获取所有方法</span> Method[] methods = student.getClass().getMethods(); <span class="hljs-keyword">for</span> (Method method : methods) { System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"method name : "</span> + method.getName()); } <span class="hljs-keyword">try</span> { <span class="hljs-comment">// 通过getMethod只能获取公有方法,如果获取私有方法则会抛出异常,比如这里就会抛异常</span> Method learnMethod = student.getClass().getMethod(<span class="hljs-string">"learn"</span>, String.class); <span class="hljs-comment">// 是否是private函数,字段是否是private也可以使用这种方式判断</span> System.<span class="hljs-keyword">out</span>.println(learnMethod.getName() + <span class="hljs-string">" is private "</span> + Modifier.isPrivate(learnMethod.getModifiers())); <span class="hljs-comment">// 调用learn函数</span> learnMethod.invoke(student, <span class="hljs-string">"java"</span>); } <span class="hljs-keyword">catch</span> (Exception e) { e.printStackTrace(); } }</code>
接口说明
<code class=" hljs oxygene"><span class="hljs-comment">// 获取Class对象中指定函数名和参数的函数,参数一为函数名,参数2为参数类型列表</span> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">Method</span> <span class="hljs-title">getDeclaredMethod</span> <span class="hljs-params">(String name, <span class="hljs-keyword">Class</span>...<?> parameterTypes)</span> // 获取该<span class="hljs-title">Class</span>对象中的所有函数<span class="hljs-params">( 不包含从父类继承的函数 )</span> <span class="hljs-title">public</span> <span class="hljs-title">Method</span>[] <span class="hljs-title">getDeclaredMethods</span> <span class="hljs-params">()</span> // 获取指定的<span class="hljs-title">Class</span>对象中的**公有**函数,参数一为函数名,参数2为参数类型列表 <span class="hljs-title">public</span> <span class="hljs-title">Method</span> <span class="hljs-title">getMethod</span> <span class="hljs-params">(String name, <span class="hljs-keyword">Class</span>...<?> parameterTypes)</span> // 获取该<span class="hljs-title">Class</span>对象中的所有**公有**函数 <span class="hljs-params">( 包含从父类和接口类集成下来的函数 )</span> <span class="hljs-title">public</span> <span class="hljs-title">Method</span>[] <span class="hljs-title">getMethods</span> <span class="hljs-params">()</span> </span></code>
这里需要注意的是getDeclaredMethod和getDeclaredMethods包含private、protected、default、public的函数,并且通过这两个函数获取到的只是在自身中定义的函数,从父类中集成的函数不能够获取到。而getMethod和getMethods只包含public函数,父类中的公有函数也能够获取到。
4 反射获取类中的字段
获取字段和章节3中获取方法是非常相似的,只是从getMethod函数换成了getField,从getDeclaredMethod换成了getDeclaredField罢了。
4.1 获取当前类中定义的字段
要获取当前类中定义的所有字段可以通过Class中的getDeclaredMethods函数,它会获取到当前类中的public、default、protected、private的所有方法。而getDeclaredMethods则是获取某个指定的方法。代码示例如下 :
<code class=" hljs cs"> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">showDeclaredFields</span>() { Student student = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">"mr.simple"</span>); <span class="hljs-comment">// 获取当前类和父类的所有公有字段</span> Field[] publicFields = student.getClass().getDeclaredFields(); <span class="hljs-keyword">for</span> (Field field : publicFields) { System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"declared field name : "</span> + field.getName()); } <span class="hljs-keyword">try</span> { <span class="hljs-comment">// 获取当前类和父类的某个公有字段</span> Field gradeField = student.getClass().getDeclaredField(<span class="hljs-string">"mGrade"</span>); <span class="hljs-comment">// 获取属性值</span> System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">" my grade is : "</span> + gradeField.getInt(student)); <span class="hljs-comment">// 设置属性值</span> gradeField.<span class="hljs-keyword">set</span>(student, <span class="hljs-number">10</span>); System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">" my grade is : "</span> + gradeField.getInt(student)); } <span class="hljs-keyword">catch</span> (Exception e) { e.printStackTrace(); } }</code>
4.2 获取当前类、父类中定义的公有字段
要获取当前类以及父类中的所有public字段可以通过Class中的getFields函数,而getField则是获取某个指定的字段。代码示例如下 :
<code class=" hljs cs"> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">showFields</span>() { Student student = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">"mr.simple"</span>); <span class="hljs-comment">// 获取当前类和父类的所有公有字段</span> Field[] publicFields = student.getClass().getFields(); <span class="hljs-keyword">for</span> (Field field : publicFields) { System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"field name : "</span> + field.getName()); } <span class="hljs-keyword">try</span> { <span class="hljs-comment">// 获取当前类和父类的某个公有字段</span> Field ageField = student.getClass().getField(<span class="hljs-string">"mAge"</span>); System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">" age is : "</span> + ageField.getInt(student)); } <span class="hljs-keyword">catch</span> (Exception e) { e.printStackTrace(); } }</code>
接口说明
<code class=" hljs oxygene"><span class="hljs-comment">// 获取Class对象中指定字段名的字段,参数一为字段名</span> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">Method</span> <span class="hljs-title">getDeclaredField</span> <span class="hljs-params">(String name)</span> // 获取该<span class="hljs-title">Class</span>对象中的所有字段<span class="hljs-params">( 不包含从父类继承的字段 )</span> <span class="hljs-title">public</span> <span class="hljs-title">Method</span>[] <span class="hljs-title">getDeclaredFields</span> <span class="hljs-params">()</span> // 获取指定的<span class="hljs-title">Class</span>对象中的**公有**字段,参数一为字段名 <span class="hljs-title">public</span> <span class="hljs-title">Method</span> <span class="hljs-title">getField</span> <span class="hljs-params">(String name)</span> // 获取该<span class="hljs-title">Class</span>对象中的所有**公有**字段 <span class="hljs-params">( 包含从父类和接口类集成下来的公有字段 )</span> <span class="hljs-title">public</span> <span class="hljs-title">Method</span>[] <span class="hljs-title">getFields</span> <span class="hljs-params">()</span> </span></code>
这里需要注意的是getDeclaredMethod和getDeclaredMethods包含private、protected、default、public的函数,并且通过这两个函数获取到的只是在自身中定义的函数,从父类中集成的函数不能够获取到。而getMethod和getMethods只包含public函数,父类中的公有函数也能够获取到。
5 反射获取父类与接口
5.1 获取父类
获取Class对象的父类。
<code class=" hljs avrasm"> Student student = new Student(<span class="hljs-string">"mr.simple"</span>)<span class="hljs-comment">;</span> Class<?> superClass = student<span class="hljs-preprocessor">.getClass</span>()<span class="hljs-preprocessor">.getSuperclass</span>()<span class="hljs-comment">;</span> while (superClass != null) { System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"Student's super class is : "</span> + superClass<span class="hljs-preprocessor">.getName</span>())<span class="hljs-comment">;</span> // 再获取父类的上一层父类,直到最后的Object类,Object的父类为null superClass = superClass<span class="hljs-preprocessor">.getSuperclass</span>()<span class="hljs-comment">;</span> }</code>
5.2 获取接口
获取Class对象中实现的接口。
<code class=" hljs cs"> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">showInterfaces</span>() { Student student = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">"mr.simple"</span>); Class<?>[] interfaceses = student.getClass().getInterfaces(); <span class="hljs-keyword">for</span> (Class<?> class1 : interfaceses) { System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"Student's interface is : "</span> + class1.getName()); } }</code>
6 获取注解信息
在框架开发中,注解加反射的组合使用是最为常见形式的。关于注解方面的知识请参考公共技术点之Java 注解 Annotation,定义注解时我们会通过@Target指定该注解能够作用的类型,看如下示例:
<code class=" hljs java"> <span class="hljs-annotation">@Target</span>({ ElementType.METHOD, ElementType.FIELD, ElementType.TYPE }) <span class="hljs-annotation">@Retention</span>(RetentionPolicy.RUNTIME) <span class="hljs-keyword">static</span> <span class="hljs-annotation">@interface</span> Test { }</code>
上述注解的@target表示该注解只能用在函数上,还有Type、Field、PARAMETER等类型,可以参考上述给出的参考资料。通过反射api我们也能够获取一个Class对象获取类型、字段、函数等相关的对象,通过这些对象的getAnnotation接口获取到对应的注解信息。
首先我们需要在目标对象上添加上注解,例如 :
<code class=" hljs java"><span class="hljs-annotation">@Test</span>(tag = <span class="hljs-string">"Student class Test Annoatation"</span>) <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Student</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Person</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Examination</span> {</span> <span class="hljs-comment">// 年级</span> <span class="hljs-annotation">@Test</span>(tag = <span class="hljs-string">"mGrade Test Annotation "</span>) <span class="hljs-keyword">int</span> mGrade; <span class="hljs-comment">// ......</span> }</code>
然后通过相关的注解函数得到注解信息,如下所示 :
<code class=" hljs avrasm"> private static void getAnnotationInfos() { Student student = new Student(<span class="hljs-string">"mr.simple"</span>)<span class="hljs-comment">;</span> Test classTest = student<span class="hljs-preprocessor">.getClass</span>()<span class="hljs-preprocessor">.getAnnotation</span>(Test<span class="hljs-preprocessor">.class</span>)<span class="hljs-comment">;</span> System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"class Annotatation tag = "</span> + classTest<span class="hljs-preprocessor">.tag</span>())<span class="hljs-comment">;</span> Field field = null<span class="hljs-comment">;</span> try { field = student<span class="hljs-preprocessor">.getClass</span>()<span class="hljs-preprocessor">.getDeclaredField</span>(<span class="hljs-string">"mGrade"</span>)<span class="hljs-comment">;</span> Test testAnnotation = field<span class="hljs-preprocessor">.getAnnotation</span>(Test<span class="hljs-preprocessor">.class</span>)<span class="hljs-comment">;</span> System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(<span class="hljs-string">"字段的Test注解tag : "</span> + testAnnotation<span class="hljs-preprocessor">.tag</span>())<span class="hljs-comment">;</span> } catch (Exception e) { e<span class="hljs-preprocessor">.printStackTrace</span>()<span class="hljs-comment">;</span> } }</code>
输出结果为 :
>
<code class=" hljs javascript"><span class="hljs-keyword">class</span> Annotatation tag = Student <span class="hljs-keyword">class</span> Test Annoatation 字段的Test注解tag : mGrade Test Annotation </code>
接口说明
<code class=" hljs cs"><span class="hljs-comment">// 获取指定类型的注解</span> <span class="hljs-keyword">public</span> <A extends Annotation> A <span class="hljs-title">getAnnotation</span>(Class<A> annotationClass) ; <span class="hljs-comment">// 获取Class对象中的所有注解</span> <span class="hljs-keyword">public</span> Annotation[] <span class="hljs-title">getAnnotations</span>() ; </code>
杂谈
反射作为Java语言的重要特性,在开发中有着极为重要的作用。很多开发框架都是基于反射来实现对目标对象的操作,而反射配合注解更是设计开发框架的主流选择,例如ActiveAndroid,因此深入了解反射的作用以及使用对于日后开发和学习必定大有益处。