class="markdown_views prism-atom-one-dark">
Java 进阶: Reflect class ="tags" href="/tags/FanShe.html" title=反射>反射机制(动态获取类内部结构和对象内容、调用方法)
简介
前一篇:Java 基础: 浅谈类型基础 - Class 对象带我们初步认识了 Class 对象有关类型的信息,然而我们真正希望做的是透过class ="tags" href="/tags/FanShe.html" title=反射>反射动态获取对象中的值或是调用对象的方法。老样子,还是我们的老朋友 Class 对象
。
参考
五分钟看懂ClassLoader https://www.jianshu.com/p/554c138ca0f5 JAVA Reflectclass ="tags" href="/tags/FanShe.html" title=反射>反射详解 https://blog.csdn.net/u014209205/article/details/80542114 试用Java中的class ="tags" href="/tags/FanShe.html" title=反射>反射reflect之getDeclaredMethods和getMethods https://www.cnblogs.com/jianjianjiao/articles/1853409.html Java Field getBoolean()用法及代码示例 https://vimsky.com/examples/usage/field-getboolean-method-in-class ="tags" href="/tags/JAVA.html" title=java>java-with-examples.html
完整测试代码地址
先附上文中用上的完整测试代码地址:https://github.com/superfreeeee/Blog-code/tree/main/back_end/class ="tags" href="/tags/JAVA.html" title=java>java/class ="tags" href="/tags/JAVA.html" title=java>java_reflect
正文
获取类定义结构
前一篇我们演示了如何获取并检查类的各种信息(访问修饰符、类/接口/枚举/注解类型、blablabla),下面我们要来获取类的内部结构
可获取内部信息总览
首先我们先来看看我们可以获取哪些内部信息
Method Description Field[] getFields() 获取成员变量列表 Field[] getDeclaredFields() 获取自有成员变量列表 Method[] getMethods() 获取方法列表 Method[] getDeclaredMethods() 获取自有方法列表 Constructor[] getConstructors() 获取构造函数列表 Constructor[] getDeclaredConstructors() 获取自有构造函数列表 Class[] getClasses() 获取内部类列表 Class[] getDeclaredClasses() 获取自有内部类列表
应该可以很清楚的发现四种内容都分为 getXXX
和 getDeclaredXXX
两个方法,其中的差异在于:
getXXX
获取所有从祖先类、接口继承或实现的访问修饰符为 public
的成员getDeclaredXXX
获取所有该类自己定义的所有(任意描述符)成员
看看下面的用例就知道了
Demo.class ="tags" href="/tags/JAVA.html" title=java>java
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">package comclass="token punctuation">. exampleclass="token punctuation">. reflectclass="token punctuation">. test1class="token punctuation">;
class="token comment">// 建立不同访问权限的各种成员
class="token keyword">public class="token keyword">class class="token class -name">Demo class="token punctuation">{
class="token comment">// 成员变量
class="token keyword">private String privateFieldclass="token punctuation">;
class="token keyword">protected String protectedFieldclass="token punctuation">;
String defaultFieldclass="token punctuation">;
class="token keyword">public String publicFieldclass="token punctuation">;
class="token comment">// 构造函数
class="token keyword">private class="token function">Demo class="token punctuation">( class="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token keyword">protected class="token function">Demo class="token punctuation">( class="token keyword">int iclass="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token function">Demo class="token punctuation">( class="token keyword">float fclass="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token keyword">public class="token function">Demo class="token punctuation">( class="token keyword">double dclass="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token comment">// 方法
class="token keyword">private class="token keyword">void class="token function">privateMethod class="token punctuation">( class="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token keyword">protected class="token keyword">void class="token function">protectedMethod class="token punctuation">( class="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token keyword">void class="token function">defaultMethod class="token punctuation">( class="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token keyword">public class="token keyword">void class="token function">publicMethod class="token punctuation">( class="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token comment">// 内部类
class="token keyword">private class="token keyword">class class="token class -name">PrivateInnerClass class="token punctuation">{ class="token punctuation">}
class="token keyword">protected class="token keyword">class class="token class -name">ProtectedInnerClass class="token punctuation">{ class="token punctuation">}
class="token keyword">class class="token class -name">DefaultInnerClass class="token punctuation">{ class="token punctuation">}
class="token keyword">public class="token keyword">class class="token class -name">PublicInnerClass class="token punctuation">{ class="token punctuation">}
class="token punctuation">}
Test.class ="tags" href="/tags/JAVA.html" title=java>java
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">package comclass="token punctuation">. exampleclass="token punctuation">. reflectclass="token punctuation">. test1class="token punctuation">;
class="token keyword">import class ="tags" href="/tags/JAVA.html" title=java>javaclass="token punctuation">. langclass="token punctuation">. reflectclass="token punctuation">. Constructorclass="token punctuation">;
class="token keyword">import class ="tags" href="/tags/JAVA.html" title=java>javaclass="token punctuation">. langclass="token punctuation">. reflectclass="token punctuation">. Fieldclass="token punctuation">;
class="token keyword">import class ="tags" href="/tags/JAVA.html" title=java>javaclass="token punctuation">. langclass="token punctuation">. reflectclass="token punctuation">. Methodclass="token punctuation">;
class="token keyword">import class ="tags" href="/tags/JAVA.html" title=java>javaclass="token punctuation">. utilclass="token punctuation">. Arraysclass="token punctuation">;
class="token keyword">public class="token keyword">class class="token class -name">Test class="token punctuation">{
class="token keyword">public class="token keyword">static class="token keyword">void class="token function">main class="token punctuation">( Stringclass="token punctuation">[ class="token punctuation">] argsclass="token punctuation">) class="token punctuation">{
Classclass="token generics function">class="token punctuation">< Democlass="token punctuation">> demoClass class="token operator">= Democlass="token punctuation">. class="token keyword">class class="token punctuation">;
class="token comment">// 查询成员变量
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- Demo fields ----- " class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Field field class="token operator">: demoClassclass="token punctuation">. class="token function">getFields class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"field: " class="token operator">+ fieldclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token operator">+ class="token string">", type: " class="token operator">+ fieldclass="token punctuation">. class="token function">getType class="token punctuation">( class="token punctuation">) class="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- Demo declared fields ----- " class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Field field class="token operator">: demoClassclass="token punctuation">. class="token function">getDeclaredFields class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"field: " class="token operator">+ fieldclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token operator">+ class="token string">", type: " class="token operator">+ fieldclass="token punctuation">. class="token function">getType class="token punctuation">( class="token punctuation">) class="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="token comment">// 查询方法
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- Demo methods ----- " class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Method method class="token operator">: demoClassclass="token punctuation">. class="token function">getMethods class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"method: " class="token operator">+ methodclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token operator">+ class="token string">", params: " class="token operator">+ Arraysclass="token punctuation">. class="token function">toString class="token punctuation">( methodclass="token punctuation">. class="token function">getParameterTypes class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- Demo declared methods ----- " class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Method method class="token operator">: demoClassclass="token punctuation">. class="token function">getDeclaredMethods class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"method: " class="token operator">+ methodclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token operator">+ class="token string">", params: " class="token operator">+ Arraysclass="token punctuation">. class="token function">toString class="token punctuation">( methodclass="token punctuation">. class="token function">getParameterTypes class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="token comment">// 查询构造函数
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- Demo constructors ----- " class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Constructor constructor class="token operator">: demoClassclass="token punctuation">. class="token function">getConstructors class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"constructor: " class="token operator">+ constructorclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token operator">+ class="token string">", params: " class="token operator">+ Arraysclass="token punctuation">. class="token function">toString class="token punctuation">( constructorclass="token punctuation">. class="token function">getParameterTypes class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- Demo declared constructors ----- " class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Constructor constructor class="token operator">: demoClassclass="token punctuation">. class="token function">getDeclaredConstructors class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"constructor: " class="token operator">+ constructorclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token operator">+ class="token string">", params: " class="token operator">+ Arraysclass="token punctuation">. class="token function">toString class="token punctuation">( constructorclass="token punctuation">. class="token function">getParameterTypes class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="token comment">// 查询内部类
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- Demo class es ----- " class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Class class="token class -name">c class="token operator">: demoClassclass="token punctuation">. class="token function">getClasses class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"class : " class="token operator">+ cclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token operator">+ class="token string">", modifiers: " class="token operator">+ cclass="token punctuation">. class="token function">getModifiers class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- Demo declared class es ----- " class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Class class="token class -name">c class="token operator">: demoClassclass="token punctuation">. class="token function">getDeclaredClasses class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"class : " class="token operator">+ cclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token operator">+ class="token string">", modifiers: " class="token operator">+ cclass="token punctuation">. class="token function">getModifiers class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="token punctuation">}
class="token punctuation">}
输出
----- Demo fields -----
field: publicField, type: class ="tags" href="/tags/JAVA.html" title=java>java.lang.String
----- Demo declared fields -----
field: privateField, type: class ="tags" href="/tags/JAVA.html" title=java>java.lang.String
field: protectedField, type: class ="tags" href="/tags/JAVA.html" title=java>java.lang.String
field: defaultField, type: class ="tags" href="/tags/JAVA.html" title=java>java.lang.String
field: publicField, type: class ="tags" href="/tags/JAVA.html" title=java>java.lang.String
----- Demo methods -----
method: publicMethod, params: []
method: wait, params: [long, int]
method: wait, params: [long]
method: wait, params: []
method: equals, params: [class class ="tags" href="/tags/JAVA.html" title=java>java.lang.Object]
method: toString, params: []
method: hashCode, params: []
method: getClass, params: []
method: notify, params: []
method: notifyAll, params: []
----- Demo declared methods -----
method: privateMethod, params: []
method: protectedMethod, params: []
method: defaultMethod, params: []
method: publicMethod, params: []
----- Demo constructors -----
constructor: com.example.reflect.test1.Demo, params: [double]
----- Demo declared constructors -----
constructor: com.example.reflect.test1.Demo, params: []
constructor: com.example.reflect.test1.Demo, params: [int]
constructor: com.example.reflect.test1.Demo, params: [float]
constructor: com.example.reflect.test1.Demo, params: [double]
----- Demo class es -----
class : com.example.reflect.test1.Demo$PublicInnerClass, modifiers: 1
----- Demo declared class es -----
class : com.example.reflect.test1.Demo$PublicInnerClass, modifiers: 1
class : com.example.reflect.test1.Demo$DefaultInnerClass, modifiers: 0
class : com.example.reflect.test1.Demo$ProtectedInnerClass, modifiers: 4
class : com.example.reflect.test1.Demo$PrivateInnerClass, modifiers: 2
下面我们将对前三种成员类型一一说明(第四种就是内部的 Class 类型,与一般的 Class 对象无异)
成员变量 Field
第一种成员类型是成员变量,定义为 class ="tags" href="/tags/JAVA.html" title=java>java.lang.reflect.Field
类型
Field 方法
首先先来看看 Field 可以调用的方法接口
Method Usage String getName() 获取变量名 Class getType()、Type getGenericType() 获取变量类型 Class getDeclaringClass() 获取成员所属类型 int getModifiers() 获取变量访问修饰符 T getT(Object) 动态获取参数对象实际成员变量值
Field 信息
FieldDemo.class ="tags" href="/tags/JAVA.html" title=java>java:成员变量示例类型
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">package comclass="token punctuation">. exampleclass="token punctuation">. reflectclass="token punctuation">. test2class="token punctuation">;
class="token keyword">public class="token keyword">class class="token class -name">FieldDemo class="token punctuation">{
class="token keyword">private class="token keyword">int privateIntclass="token punctuation">; class="token comment">// private 变量
class="token keyword">protected class="token keyword">int protectedIntclass="token punctuation">; class="token comment">// protected 变量
class="token keyword">int defaultIntclass="token punctuation">; class="token comment">// default 变量
class="token keyword">public class="token keyword">int publicIntclass="token punctuation">; class="token comment">// public 变量
class="token keyword">public class="token keyword">static class="token keyword">int publicStaticIntclass="token punctuation">; class="token comment">// public static 变量
class="token keyword">private String stringFieldclass="token punctuation">; class="token comment">// String 类型
class="token keyword">private Object objectFieldclass="token punctuation">; class="token comment">// Object 类型
class="token keyword">private class="token keyword">int class="token punctuation">[ class="token punctuation">] arrayFiledclass="token punctuation">; class="token comment">// 数组类型
class="token punctuation">}
测试方法
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">void class="token function">testFieldInfo class="token punctuation">( class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"##### testFieldInfo #####" class="token punctuation">) class="token punctuation">;
Classclass="token generics function">class="token punctuation">< FieldDemoclass="token punctuation">> fieldDemoClass class="token operator">= FieldDemoclass="token punctuation">. class="token keyword">class class="token punctuation">;
class="token comment">// getFields
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- fields ----- " class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Field field class="token operator">: fieldDemoClassclass="token punctuation">. class="token function">getFields class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( fieldclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="token comment">// getDeclaredFields
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- declared fields ----- " class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Field field class="token operator">: fieldDemoClassclass="token punctuation">. class="token function">getDeclaredFields class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( fieldclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="token comment">// fields detail
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- declared fields detail ----- " class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Field field class="token operator">: fieldDemoClassclass="token punctuation">. class="token function">getDeclaredFields class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"name: " class="token operator">+ fieldclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\ttype: " class="token operator">+ fieldclass="token punctuation">. class="token function">getType class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\tgenericType: " class="token operator">+ fieldclass="token punctuation">. class="token function">getGenericType class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\tdeclaringClass: " class="token operator">+ fieldclass="token punctuation">. class="token function">getDeclaringClass class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\tmodifiers: " class="token operator">+ fieldclass="token punctuation">. class="token function">getModifiers class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token punctuation">}
输出
##### testFieldInfo #####
----- fields -----
publicInt
publicStaticInt
----- declared fields -----
privateInt
protectedInt
defaultInt
publicInt
publicStaticInt
stringField
objectField
arrayFiled
----- declared fields detail -----
name: privateInt
type: int
genericType: int
declaringClass: class com.example.reflect.test2.FieldDemo
modifiers: 2
name: protectedInt
type: int
genericType: int
declaringClass: class com.example.reflect.test2.FieldDemo
modifiers: 4
name: defaultInt
type: int
genericType: int
declaringClass: class com.example.reflect.test2.FieldDemo
modifiers: 0
name: publicInt
type: int
genericType: int
declaringClass: class com.example.reflect.test2.FieldDemo
modifiers: 1
name: publicStaticInt
type: int
genericType: int
declaringClass: class com.example.reflect.test2.FieldDemo
modifiers: 9
name: stringField
type: class class ="tags" href="/tags/JAVA.html" title=java>java.lang.String
genericType: class class ="tags" href="/tags/JAVA.html" title=java>java.lang.String
declaringClass: class com.example.reflect.test2.FieldDemo
modifiers: 2
name: objectField
type: class class ="tags" href="/tags/JAVA.html" title=java>java.lang.Object
genericType: class class ="tags" href="/tags/JAVA.html" title=java>java.lang.Object
declaringClass: class com.example.reflect.test2.FieldDemo
modifiers: 2
name: arrayFiled
type: class [I
genericType: class [I
declaringClass: class com.example.reflect.test2.FieldDemo
modifiers: 2
Field 动态获取对象内容
测试方法
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">void class="token function">extractFieldInfo class="token punctuation">( class="token punctuation">) class="token keyword">throws NoSuchFieldExceptionclass="token punctuation">, IllegalAccessException class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"##### extractFieldInfo #####" class="token punctuation">) class="token punctuation">;
FieldDemo demo1 class="token operator">= class="token keyword">new class="token class -name">FieldDemo class="token punctuation">( class="token punctuation">) class="token punctuation">;
demo1class="token punctuation">. publicInt class="token operator">= class="token number">1 class="token punctuation">;
FieldDemo demo2 class="token operator">= class="token keyword">new class="token class -name">FieldDemo class="token punctuation">( class="token punctuation">) class="token punctuation">;
demo2class="token punctuation">. publicInt class="token operator">= class="token number">2 class="token punctuation">;
Classclass="token generics function">class="token punctuation">< FieldDemoclass="token punctuation">> fieldDemoClass class="token operator">= FieldDemoclass="token punctuation">. class="token keyword">class class="token punctuation">;
Field publicInt class="token operator">= fieldDemoClassclass="token punctuation">. class="token function">getDeclaredField class="token punctuation">( class="token string">"publicInt" class="token punctuation">) class="token punctuation">; class="token comment">// throws NoSuchFieldException
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"demo1.publicInt: " class="token operator">+ publicIntclass="token punctuation">. class="token function">getInt class="token punctuation">( demo1class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"demo2.publicInt: " class="token operator">+ publicIntclass="token punctuation">. class="token function">getInt class="token punctuation">( demo2class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token punctuation">}
输出
##### extractFieldInfo #####
demo1.publicInt: 1
demo2.publicInt: 2
方法 Method
第二种是方法,定义为 class ="tags" href="/tags/JAVA.html" title=java>java.lang.reflect.Method
Method 方法
Method Usage String getName() 获取方法名 Class getReturnType()、Type getGenericReturnType() 获取返回类型 Class[] getParameterTypes()、Type[] getGenericParameterTypes() 获取参数类型列表 Class[] getExceptionTypes()、Type[] getGenericExceptionTypes() 获取抛出异常类型列表 Class getDeclaringClass() 获取定义方法的类 Object getDefaultValue() 获取默认返回值 int getModifiers() 获取方法访问修饰符 void setAccessible(boolean) 设置调用时访问权限 Object invoke(Object, Object …args) 传入调用方法对象和参数列表,调用函数
Method 信息
MethodDemo.class ="tags" href="/tags/JAVA.html" title=java>java
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">package comclass="token punctuation">. exampleclass="token punctuation">. reflectclass="token punctuation">. test3class="token punctuation">;
class="token keyword">public class="token keyword">class class="token class -name">MethodDemo class="token punctuation">{
class="token keyword">private String nameclass="token punctuation">;
class="token keyword">public class="token function">MethodDemo class="token punctuation">( String nameclass="token punctuation">) class="token punctuation">{
class="token keyword">this class="token punctuation">. name class="token operator">= nameclass="token punctuation">;
class="token punctuation">}
class="token keyword">private class="token keyword">void class="token function">privateMethod class="token punctuation">( class="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token keyword">protected class="token keyword">void class="token function">protectedMethod class="token punctuation">( class="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token keyword">void class="token function">defaultMethod class="token punctuation">( class="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token keyword">public class="token keyword">void class="token function">publicMethod class="token punctuation">( class="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token keyword">public class="token keyword">static class="token keyword">void class="token function">publicStaticMethod class="token punctuation">( class="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token keyword">private class="token keyword">void class="token function">privateMethodWithParams class="token punctuation">( class="token keyword">int iclass="token punctuation">, class="token keyword">int jclass="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"invoke privateMethodWithParams from object: [name=" class="token operator">+ name class="token operator">+ class="token string">"], with params: [i=" class="token operator">+ i class="token operator">+ class="token string">", j=" class="token operator">+ j class="token operator">+ class="token string">"]" class="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="token keyword">void class="token function">defaultMethodWithExceptions class="token punctuation">( class="token punctuation">) class="token keyword">throws NoSuchMethodExceptionclass="token punctuation">, IllegalArgumentException class="token punctuation">{ class="token punctuation">}
class="token punctuation">}
测试方法
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">void class="token function">testMethodInfo class="token punctuation">( class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"##### testMethodInfo #####" class="token punctuation">) class="token punctuation">;
Classclass="token generics function">class="token punctuation">< MethodDemoclass="token punctuation">> c class="token operator">= MethodDemoclass="token punctuation">. class="token keyword">class class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- methods -----" class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Method method class="token operator">: cclass="token punctuation">. class="token function">getMethods class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( methodclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- declared methods -----" class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Method method class="token operator">: cclass="token punctuation">. class="token function">getDeclaredMethods class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( methodclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- declared methods detail -----" class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Method method class="token operator">: cclass="token punctuation">. class="token function">getDeclaredMethods class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"name: " class="token operator">+ methodclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\treturnType: " class="token operator">+ methodclass="token punctuation">. class="token function">getReturnType class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\tgenericReturnType: " class="token operator">+ methodclass="token punctuation">. class="token function">getGenericReturnType class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\tparameterTypes: " class="token operator">+ Arraysclass="token punctuation">. class="token function">toString class="token punctuation">( methodclass="token punctuation">. class="token function">getParameterTypes class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\tgenericParameterTypes: " class="token operator">+ Arraysclass="token punctuation">. class="token function">toString class="token punctuation">( methodclass="token punctuation">. class="token function">getGenericParameterTypes class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\texceptionTypes: " class="token operator">+ Arraysclass="token punctuation">. class="token function">toString class="token punctuation">( methodclass="token punctuation">. class="token function">getExceptionTypes class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\tgenericExceptionTypes: " class="token operator">+ Arraysclass="token punctuation">. class="token function">toString class="token punctuation">( methodclass="token punctuation">. class="token function">getGenericExceptionTypes class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\tdeclaringClass: " class="token operator">+ methodclass="token punctuation">. class="token function">getDeclaringClass class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\tdefaultValue: " class="token operator">+ methodclass="token punctuation">. class="token function">getDefaultValue class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\tmodifiers: " class="token operator">+ methodclass="token punctuation">. class="token function">getModifiers class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token punctuation">}
输出
##### testMethodInfo #####
----- methods -----
publicMethod
publicStaticMethod
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
----- declared methods -----
privateMethod
protectedMethod
privateMethodWithParams
defaultMethod
publicMethod
publicStaticMethod
defaultMethodWithExceptions
----- declared methods detail -----
name: privateMethod
returnType: void
genericReturnType: void
parameterTypes: []
genericParameterTypes: []
exceptionTypes: []
genericExceptionTypes: []
declaringClass: class com.example.reflect.test3.MethodDemo
defaultValue: null
modifiers: 2
name: protectedMethod
returnType: void
genericReturnType: void
parameterTypes: []
genericParameterTypes: []
exceptionTypes: []
genericExceptionTypes: []
declaringClass: class com.example.reflect.test3.MethodDemo
defaultValue: null
modifiers: 4
name: privateMethodWithParams
returnType: void
genericReturnType: void
parameterTypes: [int, int]
genericParameterTypes: [int, int]
exceptionTypes: []
genericExceptionTypes: []
declaringClass: class com.example.reflect.test3.MethodDemo
defaultValue: null
modifiers: 2
name: defaultMethod
returnType: void
genericReturnType: void
parameterTypes: []
genericParameterTypes: []
exceptionTypes: []
genericExceptionTypes: []
declaringClass: class com.example.reflect.test3.MethodDemo
defaultValue: null
modifiers: 0
name: publicMethod
returnType: void
genericReturnType: void
parameterTypes: []
genericParameterTypes: []
exceptionTypes: []
genericExceptionTypes: []
declaringClass: class com.example.reflect.test3.MethodDemo
defaultValue: null
modifiers: 1
name: publicStaticMethod
returnType: void
genericReturnType: void
parameterTypes: []
genericParameterTypes: []
exceptionTypes: []
genericExceptionTypes: []
declaringClass: class com.example.reflect.test3.MethodDemo
defaultValue: null
modifiers: 9
name: defaultMethodWithExceptions
returnType: void
genericReturnType: void
parameterTypes: []
genericParameterTypes: []
exceptionTypes: [class class ="tags" href="/tags/JAVA.html" title=java>java.lang.NoSuchMethodException, class class ="tags" href="/tags/JAVA.html" title=java>java.lang.IllegalArgumentException]
genericExceptionTypes: [class class ="tags" href="/tags/JAVA.html" title=java>java.lang.NoSuchMethodException, class class ="tags" href="/tags/JAVA.html" title=java>java.lang.IllegalArgumentException]
declaringClass: class com.example.reflect.test3.MethodDemo
defaultValue: null
modifiers: 0
Method 动态调用方法
测试方法
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">void class="token function">invokeMethod class="token punctuation">( class="token punctuation">) class="token keyword">throws NoSuchMethodExceptionclass="token punctuation">, IllegalAccessExceptionclass="token punctuation">, InvocationTargetException class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"##### invokeMethod #####" class="token punctuation">) class="token punctuation">;
MethodDemo demo1 class="token operator">= class="token keyword">new class="token class -name">MethodDemo class="token punctuation">( class="token string">"demo1" class="token punctuation">) class="token punctuation">;
MethodDemo demo2 class="token operator">= class="token keyword">new class="token class -name">MethodDemo class="token punctuation">( class="token string">"demo2" class="token punctuation">) class="token punctuation">;
Classclass="token generics function">class="token punctuation">< MethodDemoclass="token punctuation">> c class="token operator">= MethodDemoclass="token punctuation">. class="token keyword">class class="token punctuation">;
Method m class="token operator">= cclass="token punctuation">. class="token function">getDeclaredMethod class="token punctuation">( class="token string">"privateMethodWithParams" class="token punctuation">, class="token keyword">int class="token punctuation">. class="token keyword">class class="token punctuation">, class="token keyword">int class="token punctuation">. class="token keyword">class class="token punctuation">) class="token punctuation">;
mclass="token punctuation">. class="token function">setAccessible class="token punctuation">( class="token boolean">true class="token punctuation">) class="token punctuation">; class="token comment">// 方法内部引用私有变量,需要设置 setAccessible(true) 才能正常调用
mclass="token punctuation">. class="token function">invoke class="token punctuation">( demo1class="token punctuation">, class="token number">10 class="token punctuation">, class="token number">20 class="token punctuation">) class="token punctuation">;
mclass="token punctuation">. class="token function">invoke class="token punctuation">( demo2class="token punctuation">, class="token number">30 class="token punctuation">, class="token number">40 class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token punctuation">}
输出
##### invokeMethod #####
invoke privateMethodWithParams from object: [name=demo1], with params: [i=10, j=20]
invoke privateMethodWithParams from object: [name=demo2], with params: [i=30, j=40]
构造函数 Constructor
第三种是构造函数,定义为 class ="tags" href="/tags/JAVA.html" title=java>java.lang.reflect.Constructor
Constructor 方法
Method Usage String getName() 构造函数名(类名) Class[] getParameterTypes()、Type[] getGenericParameterTypes() 获取参数列表 int getModifiers() 获取访问修饰符
Constructor 信息
ConstructorDemo.class ="tags" href="/tags/JAVA.html" title=java>java
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">package comclass="token punctuation">. exampleclass="token punctuation">. reflectclass="token punctuation">. test4class="token punctuation">;
class="token keyword">public class="token keyword">class class="token class -name">ConstructorDemo class="token punctuation">{
class="token keyword">private class="token function">ConstructorDemo class="token punctuation">( class="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token keyword">protected class="token function">ConstructorDemo class="token punctuation">( class="token keyword">int iclass="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"create ConstructorDemo with i=" class="token operator">+ iclass="token punctuation">) class="token punctuation">;
class="token punctuation">}
class="token function">ConstructorDemo class="token punctuation">( class="token keyword">float fclass="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token keyword">public class="token function">ConstructorDemo class="token punctuation">( class="token keyword">double dclass="token punctuation">) class="token punctuation">{ class="token punctuation">}
class="token punctuation">}
测试方法
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">void class="token function">testConstructorInfo class="token punctuation">( class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"##### testConstructorInfo #####" class="token punctuation">) class="token punctuation">;
Classclass="token generics function">class="token punctuation">< ConstructorDemoclass="token punctuation">> c class="token operator">= ConstructorDemoclass="token punctuation">. class="token keyword">class class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- constructors -----" class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Constructor constructor class="token operator">: cclass="token punctuation">. class="token function">getConstructors class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( constructorclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token operator">+ class="token string">", params: " class="token operator">+ Arraysclass="token punctuation">. class="token function">toString class="token punctuation">( constructorclass="token punctuation">. class="token function">getParameterTypes class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- declared constructors -----" class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Constructor constructor class="token operator">: cclass="token punctuation">. class="token function">getDeclaredConstructors class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( constructorclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token operator">+ class="token string">", params: " class="token operator">+ Arraysclass="token punctuation">. class="token function">toString class="token punctuation">( constructorclass="token punctuation">. class="token function">getParameterTypes class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"----- declared constructors detail -----" class="token punctuation">) class="token punctuation">;
class="token keyword">for class="token punctuation">( Constructor constructor class="token operator">: cclass="token punctuation">. class="token function">getDeclaredConstructors class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"name: " class="token operator">+ constructorclass="token punctuation">. class="token function">getName class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\tparameterTypes: " class="token operator">+ Arraysclass="token punctuation">. class="token function">toString class="token punctuation">( constructorclass="token punctuation">. class="token function">getParameterTypes class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\tgenericParameterTypes: " class="token operator">+ Arraysclass="token punctuation">. class="token function">toString class="token punctuation">( constructorclass="token punctuation">. class="token function">getGenericParameterTypes class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"\tmodifiers: " class="token operator">+ constructorclass="token punctuation">. class="token function">getModifiers class="token punctuation">( class="token punctuation">) class="token punctuation">) class="token punctuation">;
class="token punctuation">}
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token punctuation">}
输出
##### testConstructorInfo #####
----- constructors -----
com.example.reflect.test4.ConstructorDemo, params: [double]
----- declared constructors -----
com.example.reflect.test4.ConstructorDemo, params: [double]
com.example.reflect.test4.ConstructorDemo, params: [float]
com.example.reflect.test4.ConstructorDemo, params: [int]
com.example.reflect.test4.ConstructorDemo, params: []
----- declared constructors detail -----
name: com.example.reflect.test4.ConstructorDemo
parameterTypes: [double]
genericParameterTypes: [double]
modifiers: 1
name: com.example.reflect.test4.ConstructorDemo
parameterTypes: [float]
genericParameterTypes: [float]
modifiers: 0
name: com.example.reflect.test4.ConstructorDemo
parameterTypes: [int]
genericParameterTypes: [int]
modifiers: 4
name: com.example.reflect.test4.ConstructorDemo
parameterTypes: []
genericParameterTypes: []
modifiers: 2
Constructor 动态创建对象实例
测试方法
class="prism language-class ="tags" href="/tags/JAVA.html" title=java>java">class="token keyword">void class="token function">invokeConstructor class="token punctuation">( class="token punctuation">) class="token keyword">throws NoSuchMethodExceptionclass="token punctuation">, InstantiationExceptionclass="token punctuation">, IllegalAccessExceptionclass="token punctuation">, InvocationTargetException class="token punctuation">{
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token string">"##### invokeConstructor #####" class="token punctuation">) class="token punctuation">;
Classclass="token generics function">class="token punctuation">< ConstructorDemoclass="token punctuation">> c class="token operator">= ConstructorDemoclass="token punctuation">. class="token keyword">class class="token punctuation">;
Constructor constructor class="token operator">= cclass="token punctuation">. class="token function">getDeclaredConstructor class="token punctuation">( class="token keyword">int class="token punctuation">. class="token keyword">class class="token punctuation">) class="token punctuation">;
ConstructorDemo demo1 class="token operator">= cclass="token punctuation">. class="token function">cast class="token punctuation">( constructorclass="token punctuation">. class="token function">newInstance class="token punctuation">( class="token number">1 class="token punctuation">) class="token punctuation">) class="token punctuation">;
ConstructorDemo demo2 class="token operator">= cclass="token punctuation">. class="token function">cast class="token punctuation">( constructorclass="token punctuation">. class="token function">newInstance class="token punctuation">( class="token number">2 class="token punctuation">) class="token punctuation">) class="token punctuation">;
Systemclass="token punctuation">. outclass="token punctuation">. class="token function">println class="token punctuation">( class="token punctuation">) class="token punctuation">;
class="token punctuation">}
输出
##### invokeConstructor #####
create ConstructorDemo with i=1
create ConstructorDemo with i=2
本人自认为代码注释的很清楚了,见文知义,就不多加解释了
结语
呼终于搞定,中间输出了很多很多信息,Field
、Method
、Constructor
、Class
等都拥有很多附带信息,这些类型相当于是把 .class 文件的类型信息都暴露出来,所以真正应用的时候可以选需要检查的部分和方法即可。
而这也是 Spring 框架中实现依赖注入(DI = Dependency Injection)
的底层原理,距离 Spring 实现原理有更进一步了,下一篇将要从 Spring Boot 的注解切入,先来看看 Java 原生的注解具备什么样的能力,来了解在 Spring 启动过程中所扮演的角色。