本章内容:
理解JAVA反射原理,运用反射API完成如下操作
动态查看类的信息
动态新建类的对象
运行时调用methods
运行时变更fields内容
动态创建数组
1.java语言的反射机制
Java 反射是Java语言的一个很重要的特征,它使得Java具有了“动态性”。
Java提供了一套机制来动态获取类的信息以及动态调用对象的方法的功能,
这套机制就叫——反射 反射机制是如今很多流行框架的实现基础,其中包括Struts、Spring、Hibernate等。
在运行时判断任意一个对象所属的类。
在运行时构造任意一个类的对象。
在运行时判断任意一个类所具有的成员变量和方法。
在运行时调用任意一个对象的方法
2.Reflection 是Java被视为动态(或准动态)语言的一个关键性质。
这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息, 包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现之interfaces(例如Serializable), 也包括fields和methods的所有信息,并可于运行时改变fields内容或调用methods
在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中:
Class类:代表一个类。
Field 类:代表类的成员变量(成员变量也称为类的属性)。
Method类:代表类的方法。
Modifier类:代表修饰符。
Constructor 类:代表类的构造方法。
Array类:提供了动态创建数组,以及访问数组的元素的静态方法
3.获取class对象
对于每一个类在加载时都会有一个唯一的Class对象,
Class对象中包含了所有需要动态获取的类的信息, 所以Class类是Reflection API 中的核心类 。
获取Class对象的方法?
obj.getClass();
class属性
Class.forName();
ClassLoader
总结:
在Class对象的方法中,所有getXXX方法只能反射出public类型的成员,包括父类的public成员,
所有getDeclaredXXX可以反射出类的所有成员(包括类的私有成员),但是只限于类本身的成员。
4.class中的常用方法(获得类的属性)
getConstructors():获得类的所有的public类型的构造方法。
getDeclaredConstructors():获得类所有的构造方法
getConstructor(Class[] parameterTypes):获得类的特定public的构造方法,parameterTypes 参数指定构造方法的参数类型。
getDeclaredConstructor(Class[] parameterTypes):获得类指定的所有的构造方法
5.class中的常用方法(获得类的方法)
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。
getMethod(String name, Class[] parameterTypes):获得类的特定public的方法, name参数指定方法的名字, parameterTypes 参数指定方法的参数类型。
getDeclaredMethod(String name, Class[] parameterTypes) Method类: getParameterTypes() :获得方法的所有参数类型 getReturnType():获得方法的返回值类型
Method类: getParameterTypes() :获得方法的所有参数类型 getReturnType():获得方法的返回值类型
代码展示:
public static void main(String[] args) { //得到Class类对象的四种方法 //第一种: Object obj=new String(); Class c1=obj.getClass(); //第二种: Class c2=String.class; //第三种: Class c3; try { c3 = Class.forName("java.lang.String"); } catch (ClassNotFoundException e) { e.printStackTrace(); } //第四种: ClassLoader c=ClassLoader.getSystemClassLoader(); try { Class c4=c.loadClass("java.util.ArrayList"); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
6.反射动态调用类的成员
调用方法步骤:
设定调用方法的参数列表(Class[])
获得调用方法的对象(Method)
设定调用方法的参数的值(Object[])
普通方法:invoke(obj,values);
构造方法:newInstance(values)
调用属性步骤:
根据属性名字获得属性对象(Field) 赋值:set(obj,value) 取值:get(obj) 如果需要强制访问类的私有成员,则需要设定: setAccessible(true);
代码展示:
public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException { // 反射String类的所有构造方法 Class c1=Students.class; //所有构造方法 Constructor[] cons=c1.getDeclaredConstructors(); for(Constructor con:cons){ // System.out.println("访问修饰权限:" + // Modifier.toString(con.getModifiers())); // System.out.println("方法名:" + con.getName()); // System.out.println("****************************"); System.out.println(Modifier.toString(con.getModifiers()) + " " + con.getName()); } //找无参的构造方法 Students s=new Students(); Constructor con = c1.getDeclaredConstructor(); Object obj = con.newInstance(); System.out.println(obj); //找带string,int类型参数的构造方法 Student s = new Student("zhangsan",12) con = c1.getDeclaredConstructor(String.class, int.class); obj = con.newInstance("zhangsan", 12); System.out.println(obj); con = c1.getDeclaredConstructor(String.class); }
总结:
Class是一个特殊的类,它的实例用来表示一个.class文件在内存中的存在形势。 反射就是照镜子,照出类的内部结构。 利用反射,可以在运行状态下初始化类。