网站建设的基本条件,crm和erp的区别,360排名优化,wordpress 本地慢目录 #0.总览
#1. 类的反射
①介绍
②获取
③作用
获取构造函数#xff1a;
创建实例#xff1a;
字段操作#xff1a;
方法操作#xff1a;
获取修饰符#xff1a;
#2.总结 #0.总览
反射#xff0c;官方是这样介绍它的#xff1a;
Reflection is a …目录 #0.总览
#1. 类的反射
①介绍
②获取
③作用
获取构造函数
创建实例
字段操作
方法操作
获取修饰符
#2.总结 #0.总览
反射官方是这样介绍它的
Reflection is a feature in the Java programming language. It allows an executing Java program to examine or introspect upon itself, and manipulate internal properties of the program.
翻译过来就是反射是 Java 编程语言中的一项功能。它允许正在执行的 Java 程序检查或“内省”自身并作程序的内部属性。
再翻译成人话就是反射可以让程序可以把本身的各种方法参数当作变量来使用。
为什么翻译成“反射”因为这个过程就像是照镜子程序通过照镜子知道自己有什么方法和参数。
详细的说有
获取类的信息类名、方法、字段、构造方法等。创建类的实例。调用类的方法、修改字段的值。动态地加载类和进行方法调用。与代理息息相关 #1. 类的反射
①介绍 首先得介绍一下Class类
Class类是反射的核心部分
Class类和真实的类对象不是一个东西Class类只是包含了对应类关于其涉及反射的一系列操作的类。每个类都会有属于自己的Class对象
列如 String.class Integer.class等
尝试输出: System.out.println(String.class); 会得到 class java.lang.String
这是类的全限定类名可以看成是类的标识。
②获取
通过一些方法我们能获得一个类的Class对象 Class ex1 Class.forName(java.lang.String); Class ex2 String.class; String string new String(); Class ex3 string.getClass(); 那获取到Class类有什么用呢
③作用
获取构造函数
拿这个类来举例
public class Temp {public int a;public int b;private int c 10;public Temp() {}public Temp(int a) {this.a a;}private Temp(int a, int b) {this.a a;this.b b;}public void sing(){System.out.println(ahhhhhh!);}private void dance(){System.out.println(haaaaaa!);}
} Class ex Temp.class; ex.getConstructor(); ex.getConstructor(int.class); 这会获得其一个指定的公共构造方法注意括号中的参数要这样写上对应的Class类才能获取到 ex.getDeclaredConstructor();则可以获取到所有构造方法 相对的Constructor?[] constructors ex.getConstructors();则会获取所有公用构造方法 getDeclaredConstructors同理 创建实例 Constructor constructor ex.getConstructor(int.class); Temp obj (Temp) constructor.newInstance( 30); 这样就根据指定的构造方法创建出了一个指定的实例 字段操作 Temp obj (Temp) constructor.newInstance( 30); Field field ex.getField(a); System.out.println(field); int value field.getInt(obj); System.out.println(value); 这里会输出 30 注意除了getInt还有getchar等对应基本数据类型其他的统一为get() 但其实get也能处理基本数据类型 格式为 Field.get(已实例化的对象) 对于私有变量无独有偶getDeclaredField(“c”)即可 但是只能System.out.println(field);即获取全限定字段名无法获得具体值 解决方法在下 但是对于字段修改 如果是公共字段 field.set(obj, 666); 就可以完成修改 私有字段是无法修改的 必须先取消限制 field.setAccessible(true); 这样才可以让私有字段像公共字段一样可以被查看修改。 方法操作
对于方法有了前面的铺垫则简单得多
对于公共方法 Class ex Temp.class; Constructor constructor ex.getConstructor(); Temp obj (Temp) constructor.newInstance(); Method greetMethod ex.getMethod(sing); greetMethod.invoke(obj); 这样就成功执行了sing方法 如果想要获取所有方法 Method[] methods ex.getMethods();即可 但是必须要有一个已经实例化的对象obj才能正常的通过invoke操作来执行方法 实际上执行的方法实际上是已经实例化的obj里面对应的方法 对于一些函数可能名字相同但是参数不同可以仿照构造函数那样加以区分 Method greetMethod ex.getMethod(sing,int.class); Method greetMethod ex.getMethod(sing,String.class);类似这样来区分 对于私有方法 和字段一模一样 在方法名上加上Declared 如getDeclaredMethodgetDeclaredMethods 然后得加上greetMethod.setAccessible(true);才能正常操作 获取修饰符 可以通过类似于 int x greetMethod.getModifiers(); 来获取任何方法/字段的修饰符,也许你会疑惑为什么是int类型原因是JAVA中的确是用数字来存储修饰符的比如说 public 1 private 2protected 3default 4 获取接口 获取接口相对来说非常简单 Class?[] interfaces ex.getInterfaces(); 这样便可获取所有ex类所实现的接口 获取注释: Annotation[] annotations ex.getAnnotations(); 这样就获取了ex类所有的注释内容 如果想获取方法的注释也非常简单 Annotation[] annotations ex.getMethod(xxx).getAnnotations(); (提一句对于每个注释都是一个单独的类型假如你需要CY注释改成 CY annotation ex.getMethod(xxx).getAnnotation();也行) 接下来想要提取注释变量什么的就随你了 这种方法可以用来实现公共字段补全 #2.总结 归功于反射机制程序得以对本身进行修改而不依赖于人工修改也提供了更多的灵活性
更是为实现动态代理提供了可能。
我也写了一篇介绍代理的文章欢迎捧场
你也许会发现这种获取参数接口方法是不是很熟悉是不是我们用的IDE就有点用了这种方式的意思不然为什么我们写了一个函数就能提示要放什么参数进去
这的确很像但实际上IDE是会实时构造一个抽象语法树AST它是代码结构的表示。这使得 IDE 能够理解类、方法、字段和参数的存在及其类型。
尽管如此反射非常重要javaspring框架里面反射无处不在
但是反射的性能开销很大因为它要在运行中实时解析类方法字段这些原本是在编译时完成的而且反射无法被编译器进行优化
所以谨慎使用