一、什么是反射
? ? ? ? java程序在运行期间能够动态加载、解析、使用一些在编译阶段并不确定的数据类型 ??
二、反射的功能
? ? ? ?2.1、加载运行时才能确定的数据类型? ? ? ?2.2、解析类的结构,获取内部信息? ? ? ?2.3、操作该类型或其实例:访问属性、调用方法、创建新对象
<span style="color: #0000ff">import <span style="color: #0000ff">static<span style="color: #000000"> java.lang.System.out;
<span style="color: #0000ff">class<span style="color: #000000"> aaa {
</span><span style="color: #0000ff">void</span><span style="color: #000000"> test() {
out.println(</span>"您好!"<span style="color: #000000">);
}
}
<span style="color: #0000ff">public <span style="color: #0000ff">class<span style="color: #000000"> ClassLoaderJZ {
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> main(String[] args) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
</span><span style="color: #008000">//</span><span style="color: #008000"> 反射的概览
</span><span style="color: #008000">//</span><span style="color: #008000"> 传统的实现test方法的调用通过如下方式</span>
aaa a1 = <span style="color: #0000ff">new</span><span style="color: #000000"> aaa();
a1.test();
</span><span style="color: #008000">//</span><span style="color: #008000"> 通过反射来实现test方法的调用</span>
aaa.<span style="color: #0000ff">class</span>.newInstance().test();<span style="color: #008000">//</span><span style="color: #008000"> 获取类模板调用方法实例化对象,最后调用test方法,更加简洁
</span><span style="color: #008000">//</span><span style="color: #008000"> 返回默认的无参构造函数 返回类型为数组</span>
out.println(aaa.<span style="color: #0000ff">class</span>.getDeclaredConstructors()[0<span style="color: #000000">]);
out.println(aaa.</span><span style="color: #0000ff">class</span>.getSuperclass());<span style="color: #008000">//</span><span style="color: #008000"> 返回aaa的父类Object
</span><span style="color: #008000">//</span><span style="color: #008000"> 输出为空可知Object已经是最高的父类了,不能再回溯了</span>
out.println(aaa.<span style="color: #0000ff">class</span><span style="color: #000000">.getSuperclass().getSuperclass());
}
}
三、获取Class对象的方法
? ? ? ?3.1、Class的静态函数forName()获取
? ? ? ?3.2、调用从Object继承下来的getClass()函数
? ? ? ?3.3、通过.class表达式获取
<span style="color: #0000ff">import <span style="color: #0000ff">static<span style="color: #000000"> java.lang.System.out;
<span style="color: #0000ff">class<span style="color: #000000"> aaa {
</span><span style="color: #0000ff">void</span><span style="color: #000000"> test() {
out.println(</span>"您好!"<span style="color: #000000">);
}
}
<span style="color: #0000ff">public <span style="color: #0000ff">class<span style="color: #000000"> ClassLoaderJZ {
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> main(String[] args) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
</span><span style="color: #008000">//</span><span style="color: #008000"> 获取Class对象的途径
</span><span style="color: #008000">//</span><span style="color: #008000"> 针对引用数据类型
</span><span style="color: #008000">//</span><span style="color: #008000">1、Class的静态函数forName()获取</span>
Class<?> c1 = Class.forName("com.study.test.aaa"<span style="color: #000000">);
out.println(c1);
</span><span style="color: #008000">//</span><span style="color: #008000"> 2、调用从Object继承下来的getClass()函数</span>
aaa a1 = <span style="color: #0000ff">new</span><span style="color: #000000"> aaa();
Class</span><?> c2 =<span style="color: #000000"> a1.getClass();
out.println(c2);
</span><span style="color: #008000">//</span><span style="color: #008000"> 3、通过.class表达式获取</span>
out.println(aaa.<span style="color: #0000ff">class</span><span style="color: #000000">);
Class</span><aaa> c3 = aaa.<span style="color: #0000ff">class</span><span style="color: #000000">;
out.println(c3);
</span><span style="color: #008000">//</span><span style="color: #008000"> 针对基本数据类型及void
</span><span style="color: #008000">//</span><span style="color: #008000"> 通过TYPE属性得到包装类的基本类型</span>
<span style="color: #0000ff">int</span> i = 1;<span style="color: #008000">//</span><span style="color: #008000"> 栈区存储 基本类型</span>
Integer j = <span style="color: #0000ff">new</span> Integer(1);<span style="color: #008000">//</span><span style="color: #008000"> 堆区存储 包装类 等于Integer j=1;</span>
Class<Integer> c4 = Integer.TYPE;<span style="color: #008000">//</span><span style="color: #008000"> 输出int 返回包装类的基本类型</span>
<span style="color: #000000"> out.println(c4);
</span><span style="color: #008000">//</span><span style="color: #008000"> 使用.class 表达式</span>
Class c5 = <span style="color: #0000ff">int</span>.<span style="color: #0000ff">class</span><span style="color: #000000">;
Class c6 </span>= <span style="color: #0000ff">double</span>.<span style="color: #0000ff">class</span><span style="color: #000000">;
Class c7 </span>= <span style="color: #0000ff">void</span>.<span style="color: #0000ff">class</span><span style="color: #000000">;
out.println(c5);
out.println(c6);
out.println(c7);
}
}
四、反射操作构造函数
? ? ? 4.1 调用无参、有一个参数、有多个参数的构造函数实例化对象
<span style="color: #0000ff">import <span style="color: #0000ff">static<span style="color: #000000"> java.lang.System.out;
<span style="color: #0000ff">import<span style="color: #000000"> java.lang.reflect.Constructor;
<span style="color: #0000ff">class<span style="color: #000000"> aaa {
aaa() {
out.println("aaa()"<span style="color: #000000">);
}
aaa(</span><span style="color: #0000ff">int</span><span style="color: #000000"> i) {
out.println(</span>"aaa(int i)"<span style="color: #000000">);
}
aaa(</span><span style="color: #0000ff">int</span><span style="color: #000000"> i,String j) {
out.println(</span>"aaa(int i,String j)"<span style="color: #000000">);
}
</span><span style="color: #0000ff">void</span><span style="color: #000000"> test() {
out.println(</span>"void test()"<span style="color: #000000">);
}
}
<span style="color: #0000ff">public <span style="color: #0000ff">class<span style="color: #000000"> ClassLoaderJZ {
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> main(String[] args) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
</span><span style="color: #008000">//</span><span style="color: #008000"> 通过反射我们获得了构造函数的规则 我们获得的是构造函数的数组</span>
out.println(aaa.<span style="color: #0000ff">class</span><span style="color: #000000">.getDeclaredConstructors().length);
</span><span style="color: #008000">//</span><span style="color: #008000"> out.println(aaa.class.getDeclaredConstructors()[0].newInstance());
</span><span style="color: #008000">//</span><span style="color: #008000"> out.println(aaa.class.getDeclaredConstructors()[1].newInstance(1));
</span><span style="color: #008000">//</span><span style="color: #008000"> 遍历输出构造函数 默认按参数个数的多少由大到小一次输出</span>
<span style="color: #0000ff">for</span> (Constructor<?> c1 : (aaa.<span style="color: #0000ff">class</span><span style="color: #000000">.getDeclaredConstructors())) {
out.println(c1);
}
</span><span style="color: #008000">//</span><span style="color: #008000"> 怎样通过反射实例化调用函数?
</span><span style="color: #008000">//</span><span style="color: #008000"> aaa.class.newInstance().test(new int[]{4,5,6});
</span><span style="color: #008000">//</span><span style="color: #008000"> 错的aaa.class.getDeclaredConstructors()[0].newInstance(1);
</span><span style="color: #008000">//</span> <span style="color: #008000">//</span><span style="color: #008000">传统方案调用test
</span><span style="color: #008000">//</span><span style="color: #008000"> aaa a1=new aaa();
</span><span style="color: #008000">//</span><span style="color: #008000"> a1.test(new int[]{1,2,3});
</span><span style="color: #008000">//</span><span style="color: #008000"> 调用无参的构造函数动态生成实例
</span><span style="color: #008000">//</span><span style="color: #008000"> aaa.class.newInstance().test();</span>
aaa.<span style="color: #0000ff">class</span>.getDeclaredConstructors()[2<span style="color: #000000">].newInstance();
</span><span style="color: #008000">//</span><span style="color: #008000"> 调用带一个参数构造函数生成实例</span>
aaa.<span style="color: #0000ff">class</span>.getDeclaredConstructors()[1].newInstance(1<span style="color: #000000">);
</span><span style="color: #008000">//</span><span style="color: #008000"> 调用带两个参数构造函数生成实例</span>
aaa.<span style="color: #0000ff">class</span>.getDeclaredConstructors()[0].newInstance(1,"abc"<span style="color: #000000">);
}
}
输出结果:
3com.study.test.aaa(int,java.lang.String)com.study.test.aaa(int)com.study.test.aaa()aaa()aaa(int i)aaa(int i,String j)
4.2 ?获取构造函数的修饰符、名字、以及参数
<span style="color: #0000ff">import <span style="color: #0000ff">static<span style="color: #000000"> java.lang.System.out;
<span style="color: #0000ff">import<span style="color: #000000"> java.lang.reflect.Constructor;
<span style="color: #0000ff">class<span style="color: #000000"> aaa {
aaa() {
out.println("aaa()"<span style="color: #000000">);
}
aaa(</span><span style="color: #0000ff">int</span><span style="color: #000000"> i) {
out.println(</span>"aaa(int i)"<span style="color: #000000">);
}
aaa(</span><span style="color: #0000ff">int</span><span style="color: #000000"> i,String j)"<span style="color: #000000">);
}
</span><span style="color: #0000ff">void</span><span style="color: #000000"> test() {
out.println(</span>"void test()"<span style="color: #000000">);
}
}
<span style="color: #0000ff">public <span style="color: #0000ff">class<span style="color: #000000"> ClassLoaderJZ {
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> main(String[] args) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
</span><span style="color: #008000">//</span><span style="color: #008000"> 通过反射我们获得了构造函数的规则 我们获得的是构造函数的数组</span>
out.println(aaa.<span style="color: #0000ff">class</span><span style="color: #000000">.getDeclaredConstructors().length);
</span><span style="color: #008000">//</span><span style="color: #008000"> out.println(aaa.class.getDeclaredConstructors()[0].newInstance());
</span><span style="color: #008000">//</span><span style="color: #008000"> out.println(aaa.class.getDeclaredConstructors()[1].newInstance(1));
</span><span style="color: #008000">//</span><span style="color: #008000"> 遍历输出构造函数 默认按参数个数的多少由大到小一次输出
</span><span style="color: #008000">//</span><span style="color: #008000"> getConstructors()函数获取public的构造函数;getDeclaredConstructors()获取所有的构造函数</span>
<span style="color: #0000ff">for</span> (Constructor<?> c1 : (aaa.<span style="color: #0000ff">class</span><span style="color: #000000">.getDeclaredConstructors())) {
</span><span style="color: #008000">//</span><span style="color: #008000"> 获取构造函数的修饰符、名字、参数类型</span>
out.println("获取构造函数的修饰符、名字、参数类型"<span style="color: #000000">);
out.println(c1.getModifiers());
out.println(c1.getName());
</span><span style="color: #0000ff">for</span><span style="color: #000000"> (Class c2 : c1.getParameterTypes()) {
out.println(c2);
}
}
}
}
输出结果:
3获取构造函数的修饰符、名字、参数类型0com.study.test.aaaintclass java.lang.String获取构造函数的修饰符、名字、参数类型0com.study.test.aaaint获取构造函数的修饰符、名字、参数类型0com.study.test.aaa
五、反射获取接口.
<span style="color: #0000ff">import <span style="color: #0000ff">static<span style="color: #000000"> java.lang.System.out;
<span style="color: #0000ff">interface<span style="color: #000000"> I1 {
}
<span style="color: #0000ff">interface<span style="color: #000000"> I2 {
}
<span style="color: #0000ff">class aaa <span style="color: #0000ff">implements<span style="color: #000000"> I1,I2 {
<span style="color: #0000ff">public<span style="color: #000000"> aaa() {
out.println("aaa()"<span style="color: #000000">);
}
</span><span style="color: #0000ff">private</span> aaa(<span style="color: #0000ff">int</span><span style="color: #000000"> i) {
out.println(</span>"aaa(int i)"<span style="color: #000000">);
}
</span><span style="color: #0000ff">protected</span> aaa(<span style="color: #0000ff">int</span><span style="color: #000000"> i,String j)"<span style="color: #000000">);
}
</span><span style="color: #0000ff">void</span><span style="color: #000000"> test() {
out.println(</span>"void test()"<span style="color: #000000">);
}
}
<span style="color: #0000ff">public <span style="color: #0000ff">class<span style="color: #000000"> ClassLoaderJZ {
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> main(String[] args) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
</span><span style="color: #008000">//</span><span style="color: #008000"> 获取接口</span>
out.println("获取接口"<span style="color: #000000">);
</span><span style="color: #0000ff">for</span> (Class<?> c2 : aaa.<span style="color: #0000ff">class</span><span style="color: #000000">.getInterfaces()) {
out.println(c2);
}
}
}
输出结果:
获取接口interface com.study.test.I1interface com.study.test.I2
六、反射获取方法的返回类型,修饰符,参数类型等等
<span style="color: #0000ff">import <span style="color: #0000ff">static<span style="color: #000000"> java.lang.System.out;
<span style="color: #0000ff">import<span style="color: #000000"> java.lang.reflect.Method;
<span style="color: #0000ff">interface<span style="color: #000000"> I1 {
}
<span style="color: #0000ff">interface<span style="color: #000000"> I2 {
}
<span style="color: #0000ff">class aaa <span style="color: #0000ff">implements<span style="color: #000000"> I1,String j)"<span style="color: #000000">);
}
</span><span style="color: #0000ff">void</span> test() <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
out.println(</span>"void test()"<span style="color: #000000">);
}
</span><span style="color: #0000ff">void</span><span style="color: #000000"> test1() {
out.println(</span>"void test1()"<span style="color: #000000">);
}
</span><span style="color: #0000ff">void</span><span style="color: #000000"> test2() {
out.println(</span>"void test2()"<span style="color: #000000">);
}
}
<span style="color: #0000ff">public <span style="color: #0000ff">class<span style="color: #000000"> ClassLoaderJZ {
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> main(String[] args) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
</span><span style="color: #008000">//</span><span style="color: #008000"> getMethod()方法获得所有public的方法包括从Object继承的方法
</span><span style="color: #008000">//</span><span style="color: #008000"> for(Method m:aaa.class.getMethods()){
</span><span style="color: #008000">//</span><span style="color: #008000"> out.println(m);
</span><span style="color: #008000">//</span><span style="color: #008000"> };
</span><span style="color: #008000">//</span><span style="color: #008000"> getDeclaredMethods()方法获得所有在本类中自己声明的方法</span>
<span style="color: #0000ff">for</span> (Method m : aaa.<span style="color: #0000ff">class</span><span style="color: #000000">.getDeclaredMethods()) {
out.println(</span>"输出方法的返回类型,参数类型,修饰符,以及方法的异常类型"<span style="color: #000000">);
out.println(m.getReturnType());
out.println(m.getParameters().length);
out.println(m.getModifiers());
</span><span style="color: #0000ff">for</span><span style="color: #000000"> (Class c : m.getExceptionTypes()) {
out.println(m);
}
}
}
}
输出结果:
输出方法的返回类型,参数类型,修饰符,以及方法的异常类型void00void com.study.test.aaa.test() throws java.lang.Exception输出方法的返回类型,参数类型,修饰符,以及方法的异常类型void00输出方法的返回类型,参数类型,修饰符,以及方法的异常类型void00
七、通过反射调用方法
<span style="color: #0000ff">import <span style="color: #0000ff">static java.lang.System.*<span style="color: #000000">;
<span style="color: #0000ff">import<span style="color: #000000"> java.lang.reflect.Constructor;
<span style="color: #0000ff">import<span style="color: #000000"> java.lang.reflect.Method;
<span style="color: #0000ff">interface<span style="color: #000000"> I1 {
}
<span style="color: #0000ff">interface<span style="color: #000000"> I2 {
}
<span style="color: #0000ff">class aaa <span style="color: #0000ff">implements<span style="color: #000000"> I1,I2 {
</span><span style="color: #0000ff">public</span><span style="color: #000000"> aaa() {
out.println(</span>"aaa()"<span style="color: #000000">);
}
</span><span style="color: #0000ff">public</span> aaa(<span style="color: #0000ff">int</span><span style="color: #000000"> i) {
out.println(</span>"aaa(int i)"<span style="color: #000000">);
}
</span><span style="color: #0000ff">protected</span> aaa(<span style="color: #0000ff">int</span> i,<span style="color: #0000ff">int</span><span style="color: #000000"> j) {
out.println(</span>"aaa(int i,String j)"<span style="color: #000000">);
}
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> test() {
out.println(</span>"void test()"<span style="color: #000000">);
}
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> test1(<span style="color: #0000ff">int</span><span style="color: #000000"> i) {
out.println(</span>"void test1()"<span style="color: #000000">);
}
</span><span style="color: #0000ff">void</span> test2(<span style="color: #0000ff">int</span> j,<span style="color: #0000ff">int</span><span style="color: #000000"> k) {
out.println(</span>"void test2()"<span style="color: #000000">);
}
}
<span style="color: #0000ff">public <span style="color: #0000ff">class<span style="color: #000000"> ClassLoaderJZ {
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> main(String[] args) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
</span><span style="color: #008000">//</span><span style="color: #008000"> getMethod()方法获得所有public的方法包括从Object继承的方法
</span><span style="color: #008000">//</span><span style="color: #008000"> for(Method m:aaa.class.getMethods()){
</span><span style="color: #008000">//</span><span style="color: #008000"> out.println(m);
</span><span style="color: #008000">//</span><span style="color: #008000"> };
</span><span style="color: #008000">//</span><span style="color: #008000"> getDeclaredMethods()方法获得所有在本类中自己声明的方法</span>
out.println("获得所有在本类中自己声明的方法"<span style="color: #000000">);
</span><span style="color: #0000ff">for</span> (Method m : aaa.<span style="color: #0000ff">class</span><span style="color: #000000">.getDeclaredMethods()) {
out.println(m);
}
</span><span style="color: #008000">//</span><span style="color: #008000"> 注意:遍历出的构造函数是无序的</span>
out.println("构造函数"<span style="color: #000000">);
</span><span style="color: #0000ff">for</span> (Constructor c : aaa.<span style="color: #0000ff">class</span><span style="color: #000000">.getDeclaredConstructors()) {
out.println(c);
}
out.println(</span>"方法调用"<span style="color: #000000">);
aaa.</span><span style="color: #0000ff">class</span>.getDeclaredMethods()[0].invoke(aaa.<span style="color: #0000ff">class</span>.getDeclaredConstructors()[2].newInstance(),<span style="color: #0000ff">null</span><span style="color: #000000">);
aaa.</span><span style="color: #0000ff">class</span>.getDeclaredMethods()[1].invoke(aaa.<span style="color: #0000ff">class</span>.getDeclaredConstructors()[1].newInstance(1),1<span style="color: #000000">);
}
}
输出结果:
获得所有在本类中自己声明的方法public void com.study.test.aaa.test()public void com.study.test.aaa.test1(int)void com.study.test.aaa.test2(int,int)构造函数protected com.study.test.aaa(int,int)public com.study.test.aaa(int)public com.study.test.aaa()方法调用aaa()void test()aaa(int i)void test1()
八、反射得到所有的字段
<span style="color: #0000ff">import <span style="color: #0000ff">static<span style="color: #000000"> java.lang.System.out;
<span style="color: #0000ff">import<span style="color: #000000"> java.io.IOException;
<span style="color: #0000ff">import<span style="color: #000000"> java.lang.reflect.Field;
<span style="color: #0000ff">class<span style="color: #000000"> aa {
<span style="color: #0000ff">private <span style="color: #0000ff">int j = 2<span style="color: #000000">;
<span style="color: #0000ff">public <span style="color: #0000ff">static <span style="color: #0000ff">int i = 1<span style="color: #000000">;
</span><span style="color: #0000ff">void</span> test1(<span style="color: #0000ff">int</span> i) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception,IOException {
out.println(</span>"test"<span style="color: #000000">);
}
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">int</span><span style="color: #000000"> test2() {
out.println(</span>"test1"<span style="color: #000000">);
</span><span style="color: #0000ff">return</span> 1<span style="color: #000000">;
}
}
<span style="color: #0000ff">public <span style="color: #0000ff">class<span style="color: #000000"> ClassLoaderJZ {
<span style="color: #0000ff">public <span style="color: #0000ff">static <span style="color: #0000ff">void main(String[] args) <span style="color: #0000ff">throws<span style="color: #000000"> NoSuchFieldException,SecurityException,IllegalArgumentException,IllegalAccessException,InstantiationException {
<span style="color: #008000">//<span style="color: #008000"> 得到第一个字段内容
Field f1 = aa.<span style="color: #0000ff">class.getDeclaredField("j"<span style="color: #000000">);
f1.setAccessible(<span style="color: #0000ff">true<span style="color: #000000">);
out.println(f1.get(aa.<span style="color: #0000ff">class<span style="color: #000000">.newInstance()));
<span style="color: #008000">//<span style="color: #008000"> 得到第二个字段内容
out.println(aa.<span style="color: #0000ff">class.getDeclaredField("i").get(<span style="color: #0000ff">null<span style="color: #000000">));
}
}
输出结果:
21 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|