ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JAVA-反射

2021-11-13 12:35:33  阅读:161  来源: 互联网

标签:反射 JAVA Users repository jar wuxiong m2 wx


参考:https://www.liaoxuefeng.com/wiki/1252599548343744/1255945147512512

 

基本逻辑

  1 package reflection;
  2 
  3 import java.lang.reflect.Constructor;
  4 import java.lang.reflect.Field;
  5 import java.lang.reflect.Method;
  6 
  7 /**
  8  * 教程:https://www.liaoxuefeng.com/wiki/1252599548343744/1264799402020448
  9  * class是由JVM在执行过程中动态加载的。JVM在第一次读取到一种class类型时,将其加载进内存。
 10  * 每加载一种class,JVM就为其创建一个Class类型的实例,并关联起来。注意:这里的Class类型是一个名叫Class的class。
 11  */
 12 public class MainTest2 {
 13 
 14     public static void main(String[] args) {
 15         /**
 16          * 由于JVM为每个加载的class创建了对应的Class实例,并在实例中保存了该class的所有信息,包括类名、包名、父类、实现的接口、
 17          * 所有方法、字段等,因此,如果获取了某个Class实例,我们就可以通过这个Class实例获取到该实例对应的class的所有信息。
 18          *
 19          * 这种通过Class实例获取class信息的方法称为反射(Reflection)。
 20          *
 21          * 如何获取一个class的Class实例?有三个方法:
 22          */
 23 
 24 
 25         // 方法1
 26         Class cls1 = String.class;
 27 
 28         // 方法2
 29         String s = "Hello";
 30         Class cls2 = s.getClass();  // 通过实例变量的getClass()获得
 31 
 32         // 方法3
 33         try {
 34             Class cls3 = Class.forName("java.lang.String");
 35         } catch (ClassNotFoundException e) {
 36             e.printStackTrace();
 37         }
 38 
 39         // 因为Class实例在JVM中是唯一的,所以,上述方法获取的Class实例是同一个实例。可以用==比较两个Class实例:
 40 
 41 
 42         /**通过Class实例获取相关信息**/
 43         Class clsStu = Student.class;
 44 
 45         System.out.println(clsStu.getClassLoader());
 46         System.out.println(clsStu.getName());
 47         try {
 48             System.out.println(clsStu.getConstructor());
 49         } catch (NoSuchMethodException e) {
 50             e.printStackTrace();
 51         }
 52         System.out.println(clsStu.getDeclaredFields().toString());
 53         System.out.println(clsStu.getFields().toString());
 54         try {
 55             System.out.println(clsStu.getField("grade"));
 56         } catch (NoSuchFieldException e) {
 57             e.printStackTrace();
 58         }
 59         try {
 60             System.out.println(clsStu.getField("score"));
 61         } catch (NoSuchFieldException e) {
 62             e.printStackTrace();
 63         }
 64         try {
 65             System.out.println(clsStu.getField("name"));
 66             Field field = clsStu.getField("name");
 67             System.out.println("type=" + field.getType() + ", name=" + field.getName() + ", ");
 68         } catch (NoSuchFieldException e) {
 69             e.printStackTrace();
 70         }
 71 
 72 
 73 
 74         try {
 75 
 76             /**通过Class实例调用方法**/
 77             String str = "helloWorld";
 78             Class clsz1 = str.getClass();
 79             Class clsz2 = String.class;
 80             Class clsz3 = Class.forName("java.lang.String");
 81 
 82             System.out.println("1Equal2:" + clsz1.equals(clsz2) + ", 1Equal3:" + clsz1.equals(clsz3));  // true  true
 83             System.out.println("1==2:" + (clsz1 == clsz2) + ", 1==3:" + (clsz1 == clsz3));  // true  true
 84 
 85             Method method = clsz2.getMethod("substring", int.class, int.class);
 86             System.out.println("substring=" + method.invoke(str, 0, 3));
 87 
 88 
 89 
 90             Method m = Integer.class.getMethod("parseInt", String.class);
 91             // 调用该静态方法parseInt,无需传入对象(传null即可)
 92             Integer n = (Integer) m.invoke(null, "12345");
 93             System.out.println("n=" + n);
 94 
 95 
 96             /**通过Class实例调用构造方法**/
 97             Person p1 = new Person();
 98             Person p2 = Person.class.newInstance();  // 调用Class.newInstance()的局限是,它只能调用该类的public无参数构造方法
 99             System.out.println("p1.equals.p2:"  + p1.equals(p2));  // false
100             System.out.println("p1==p2:"  + p1.equals(p2));  // false
101 
102             // 使用 Java的反射API提供的Constructor对象
103             Constructor constructor1 = Integer.class.getConstructor(String.class);  // 获取Integer参数类型为String的构造方法
104             int resInt = (int) constructor1.newInstance("987");
105             System.out.println("resInt=" + resInt);
106 
107 
108 
109         } catch (Exception e) {
110             e.printStackTrace();
111         }
112 
113 
114     }
115 
116     static class Person{
117         public String name;
118     }
119 
120     class Student extends Person {
121         public int score;
122         private int grade;
123     }
124 }
View Code

执行结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/bin/java -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/tools.jar:/Users/wuxiong.wx/work/code/testDemo/target/classes:/Users/wuxiong.wx/.m2/repository/org/springframework/spring/999-not-exist/spring-999-not-exist.jar:/Users/wuxiong.wx/.m2/repository/org/springframework/spring-core/4.3.2.RELEASE/spring-core-4.3.2.RELEASE.jar:/Users/wuxiong.wx/.m2/repository/commons-logging/commons-logging/1.2/commons-logging-1.2.jar:/Users/wuxiong.wx/.m2/repository/org/springframework/spring-beans/4.3.2.RELEASE/spring-beans-4.3.2.RELEASE.jar:/Users/wuxiong.wx/.m2/repository/org/springframework/spring-aop/4.3.2.RELEASE/spring-aop-4.3.2.RELEASE.jar:/Users/wuxiong.wx/.m2/repository/org/springframework/spring-context/4.3.2.RELEASE/spring-context-4.3.2.RELEASE.jar:/Users/wuxiong.wx/.m2/repository/org/springframework/spring-expression/4.3.2.RELEASE/spring-expression-4.3.2.RELEASE.jar:/Users/wuxiong.wx/.m2/repository/org/springframework/spring-context-support/4.3.2.RELEASE/spring-context-support-4.3.2.RELEASE.jar:/Users/wuxiong.wx/.m2/repository/org/springframework/spring-tx/4.3.2.RELEASE/spring-tx-4.3.2.RELEASE.jar:/Users/wuxiong.wx/.m2/repository/org/springframework/spring-jdbc/4.3.2.RELEASE/spring-jdbc-4.3.2.RELEASE.jar:/Users/wuxiong.wx/.m2/repository/org/springframework/spring-orm/4.3.2.RELEASE/spring-orm-4.3.2.RELEASE.jar:/Users/wuxiong.wx/.m2/repository/org/springframework/spring-web/4.3.2.RELEASE/spring-web-4.3.2.RELEASE.jar:/Users/wuxiong.wx/.m2/repository/org/springframework/spring-webmvc/4.3.2.RELEASE/spring-webmvc-4.3.2.RELEASE.jar:/Users/wuxiong.wx/.m2/repository/org/springframework/spring-test/4.3.2.RELEASE/spring-test-4.3.2.RELEASE.jar:/Users/wuxiong.wx/.m2/repository/org/aspectj/aspectjrt/1.8.8/aspectjrt-1.8.8.jar:/Users/wuxiong.wx/.m2/repository/org/aspectj/aspectjweaver/1.8.8/aspectjweaver-1.8.8.jar:/Users/wuxiong.wx/.m2/repository/junit/junit/4.12/junit-4.12.jar:/Users/wuxiong.wx/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/Users/wuxiong.wx/.m2/repository/io/appium/java-client/7.0.0/java-client-7.0.0.jar:/Users/wuxiong.wx/.m2/repository/org/seleniumhq/selenium/selenium-java/3.141.59/selenium-java-3.141.59.jar:/Users/wuxiong.wx/.m2/repository/org/seleniumhq/selenium/selenium-chrome-driver/3.141.59/selenium-chrome-driver-3.141.59.jar:/Users/wuxiong.wx/.m2/repository/org/seleniumhq/selenium/selenium-edge-driver/3.141.59/selenium-edge-driver-3.141.59.jar:/Users/wuxiong.wx/.m2/repository/org/seleniumhq/selenium/selenium-firefox-driver/3.141.59/selenium-firefox-driver-3.141.59.jar:/Users/wuxiong.wx/.m2/repository/org/seleniumhq/selenium/selenium-ie-driver/3.141.59/selenium-ie-driver-3.141.59.jar:/Users/wuxiong.wx/.m2/repository/org/seleniumhq/selenium/selenium-opera-driver/3.141.59/selenium-opera-driver-3.141.59.jar:/Users/wuxiong.wx/.m2/repository/org/seleniumhq/selenium/selenium-remote-driver/3.141.59/selenium-remote-driver-3.141.59.jar:/Users/wuxiong.wx/.m2/repository/org/seleniumhq/selenium/selenium-safari-driver/3.141.59/selenium-safari-driver-3.141.59.jar:/Users/wuxiong.wx/.m2/repository/net/bytebuddy/byte-buddy/1.8.15/byte-buddy-1.8.15.jar:/Users/wuxiong.wx/.m2/repository/org/apache/commons/commons-exec/1.3/commons-exec-1.3.jar:/Users/wuxiong.wx/.m2/repository/com/google/guava/guava/25.0-jre/guava-25.0-jre.jar:/Users/wuxiong.wx/.m2/repository/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar:/Users/wuxiong.wx/.m2/repository/org/checkerframework/checker-compat-qual/2.0.0/checker-compat-qual-2.0.0.jar:/Users/wuxiong.wx/.m2/repository/com/google/errorprone/error_prone_annotations/2.1.3/error_prone_annotations-2.1.3.jar:/Users/wuxiong.wx/.m2/repository/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.jar:/Users/wuxiong.wx/.m2/repository/org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14.jar:/Users/wuxiong.wx/.m2/repository/com/squareup/okhttp3/okhttp/3.11.0/okhttp-3.11.0.jar:/Users/wuxiong.wx/.m2/repository/com/squareup/okio/okio/1.14.0/okio-1.14.0.jar:/Users/wuxiong.wx/.m2/repository/org/seleniumhq/selenium/selenium-support/3.141.59/selenium-support-3.141.59.jar:/Users/wuxiong.wx/.m2/repository/org/seleniumhq/selenium/selenium-api/3.141.59/selenium-api-3.141.59.jar:/Users/wuxiong.wx/.m2/repository/com/google/code/gson/gson/2.8.5/gson-2.8.5.jar:/Users/wuxiong.wx/.m2/repository/org/apache/httpcomponents/httpclient/4.5.6/httpclient-4.5.6.jar:/Users/wuxiong.wx/.m2/repository/org/apache/httpcomponents/httpcore/4.4.10/httpcore-4.4.10.jar:/Users/wuxiong.wx/.m2/repository/commons-codec/commons-codec/1.10/commons-codec-1.10.jar:/Users/wuxiong.wx/.m2/repository/cglib/cglib/3.2.8/cglib-3.2.8.jar:/Users/wuxiong.wx/.m2/repository/org/ow2/asm/asm/6.2.1/asm-6.2.1.jar:/Users/wuxiong.wx/.m2/repository/org/apache/ant/ant/1.10.3/ant-1.10.3.jar:/Users/wuxiong.wx/.m2/repository/org/apache/ant/ant-launcher/1.10.3/ant-launcher-1.10.3.jar:/Users/wuxiong.wx/.m2/repository/commons-validator/commons-validator/1.6/commons-validator-1.6.jar:/Users/wuxiong.wx/.m2/repository/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.jar:/Users/wuxiong.wx/.m2/repository/commons-digester/commons-digester/1.8.1/commons-digester-1.8.1.jar:/Users/wuxiong.wx/.m2/repository/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar:/Users/wuxiong.wx/.m2/repository/org/apache/commons/commons-lang3/3.8/commons-lang3-3.8.jar:/Users/wuxiong.wx/.m2/repository/commons-io/commons-io/2.6/commons-io-2.6.jar:/Users/wuxiong.wx/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar:/Users/wuxiong.wx/.m2/repository/com/alibaba/fastjson/1.2.60/fastjson-1.2.60.jar reflection.MainTest2
sun.misc.Launcher$AppClassLoader@135fbaa4
reflection.MainTest2$Student
[Ljava.lang.reflect.Field;@7ea987ac
[Ljava.lang.reflect.Field;@5cad8086
public int reflection.MainTest2$Student.score
public java.lang.String reflection.MainTest2$Person.name
type=class java.lang.String, name=name, 
1Equal2:true, 1Equal3:true
1==2:true, 1==3:true
substring=hel
n=12345
p1.equals.p2:false
p1==p2:false
resInt=987
java.lang.NoSuchMethodException: reflection.MainTest2$Student.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.getConstructor(Class.java:1825)
    at reflection.MainTest2.main(MainTest2.java:48)
java.lang.NoSuchFieldException: grade
    at java.lang.Class.getField(Class.java:1703)
    at reflection.MainTest2.main(MainTest2.java:55)

Process finished with exit code 0

 

动态代理

https://www.liaoxuefeng.com/wiki/1252599548343744/1264804593397984

另外的总结:https://www.zhihu.com/question/20794107/answer/604485904

 

有没有可能不编写实现类,直接在运行期创建某个interface的实例呢?

这是可能的,因为Java标准库提供了一种动态代理(Dynamic Proxy)的机制:可以在运行期动态创建某个interface的实例。

什么叫运行期动态创建?听起来好像很复杂。所谓动态代理,是和静态相对应的。我们来看静态代码怎么写:

定义接口:

1 public interface Hello {
2     void morning(String name);
3 }

编写实现类:

1 public class HelloWorld implements Hello {
2     public void morning(String name) {
3         System.out.println("Good morning, " + name);
4     }
5 }

创建实例,转型为接口并调用:

1 Hello hello = new HelloWorld();
2 hello.morning("Bob");

 

还有一种方式是动态代码,我们仍然先定义了接口Hello,但是我们并不去编写实现类,而是直接通过JDK提供的一个Proxy.newProxyInstance()创建了一个Hello接口对象。这种没有实现类但是在运行期动态创建了一个接口对象的方式,我们称为动态代码。JDK提供的动态创建接口对象的方式,就叫动态代理。

 1 import java.lang.reflect.InvocationHandler;
 2 import java.lang.reflect.Method;
 3 import java.lang.reflect.Proxy;
 4 
 5 public class Main {
 6     public static void main(String[] args) {
 7         InvocationHandler handler = new InvocationHandler() {
 8             @Override
 9             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
10                 System.out.println(method);
11                 if (method.getName().equals("morning")) {
12                     System.out.println("Good morning, " + args[0]);
13                 }
14                 return null;
15             }
16         };
17         Hello hello = (Hello) Proxy.newProxyInstance(
18             Hello.class.getClassLoader(), // 传入ClassLoader
19             new Class[] { Hello.class }, // 传入要实现的接口
20             handler); // 传入处理调用方法的InvocationHandler
21         hello.morning("Bob");
22     }
23 }
24 
25 interface Hello {
26     void morning(String name);
27 }
View Code
public abstract void Hello.morning(java.lang.String)
Good morning, Bob

 

标签:反射,JAVA,Users,repository,jar,wuxiong,m2,wx
来源: https://www.cnblogs.com/wxdlut/p/15547739.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有