反射的用途及实现
Posted goodbye-lazy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射的用途及实现相关的知识,希望对你有一定的参考价值。
反射 (Reflection) 是 Java 的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性。
其核心是JVM 在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。
一.主要的功能:
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法);
- 在运行时调用任意一个对象的方法
二.反射最重要的用途就是开发各种通用框架:
1.各种框架:(spring,struts....)用反射,运行时动态加载需要加载的对象。
2.各种IDE开发工具:当我们输入一个对象或类并想调用它的属性或方法时,一按点号,编译器就会自动列出它的属性或方法,这里就会用到反射。
三.基本运用:
1.获得Class对象
(1) 使用 Class 类的 forName
静态方法:
public static Class<?> forName(String className)
比如在 JDBC 开发中常用此方法加载数据库驱动:
getClass()
方法instanceof
关键字来判断是否为某个类的实例。同时我们也可以借助反射中 Class 对象的 isInstance()
方法来判断是否为某个类的实例,它是一个 native 方法:getDeclaredMethods
方法返回类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。getMethods
方法返回某个类的所有公用(public)方法,包括其继承类的公用方法getMethod
方法返回一个特定的方法,其中第一个参数为方法名称,后面的参数为方法的参数对应Class的对象public T newInstance(Object ... initargs)
getFiled
:访问公有的成员变量getDeclaredField
:所有已声明的成员变量,但不能得到其父类的成员变量getFileds
和 getDeclaredFields
方法用法同上(参照 Method)。invoke()
方法来调用这个方法。invoke
方法的原型为:public static void testArray() throws ClassNotFoundException { Class<?> cls = Class.forName("java.lang.String"); Object array = Array.newInstance(cls,25); //往数组里添加内容 Array.set(array,0,"hello"); Array.set(array,1,"Java"); Array.set(array,2,"fuck"); Array.set(array,3,"Scala"); Array.set(array,4,"Clojure"); //获取某一项的内容 System.out.println(Array.get(array,3)); }
其中的Array类为java.lang.reflect.Array类。我们通过Array.newInstance()创建数组对象,它的原型是:
public static Object newInstance(Class<?> componentType, int length) throws NegativeArraySizeException { return newArray(componentType, length); }
而 newArray
方法是一个 native 方法,它在 HotSpot JVM 里的具体实现我们后边再研究,这里先把源码贴出来:
private static native Object newArray(Class<?> componentType, int length) throws NegativeArraySizeException;
另外,Array 类的 set
和 get
方法都为 native 方法,在 HotSpot JVM 里分别对应 Reflection::array_set
和 Reflection::array_get
方法.
四.注意事项
反射会额外消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么就不需要用反射。
另外,反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。
以上是关于反射的用途及实现的主要内容,如果未能解决你的问题,请参考以下文章
2018.5.12说说反射的用途及实现------要再花费时间加强理解
在Tomcat的安装目录下conf目录下的server.xml文件中增加一个xml代码片段,该代码片段中每个属性的含义与用途