一,前言
理解反射的概念,掌握4个反射相关的类,掌握实例化方式和常用方法,掌握反射实例化对象在实操中的使用。
二,反射的概念
反射(Reflection),它允许在运行中的Java程序获取自身的信息,并且可以操作类或者对象的内部属性。
(java.lang):Class
(java.lang.reflect):Field,Method,Constructor
三,反射相关的类
1.Class类
概念:
Class,类对象,描述的是类的信息(注意,描述的是类,而不是对象)。
三种实例化方式:
//方式一:调用运行时类的属性:.class Class clazz1 = Person.class; //方式二:调用运行时类的对象,调用getClass() Person p1 = new Person(); Clss clazz2 = p1.getClass(); //方式三:调用Class的静态方法:forName(String classPath) Class clazz3 = Class.ForName("com.xxx.xxx.Person");
通过反射创建运行时类的对象:
//调用newInstance方法创建对象 Person obj = (Person)clazz.newInstance(); //注:1.运行时类必须提供空参构造器 2.空参构造器的访问权限足够
常用方法:
//获取运行时类的父类 Class superclass = clazz.getSuperclass(); //获取运行时类实现的接口 Class[] interfaces = clazz.getInterfaces(); //获取运行时类所在的包 Package pack = clazz.getPackage(); //获取运行时类声明的注解 Annotation[] annotations = clazz.getAnnotations(); // 获取类的所有权限为public的变量(包括该类和超类或者超接口) public Field[] getFields() throws SecurityException {} // 获取本类的所有变量 public Field[] getDeclaredFields() throws SecurityException {} // 获取类的所有权限为public的方法(包括该类和超类或者超接口) public Method[] getMethods() throws SecurityException {} // 获取本类的所有成员方法 public Method[] getDeclaredMethods() throws SecurityException {} // 获取类的所有权限为public的构造方法 public Constructor<?>[] getConstructors() throws SecurityException {} // 获取本类的所有构造方法 public Constructor<?>[] getDeclaredConstructors() throws SecurityException {} // 根据类对象获取类名 public String getName() {} // 判断当前的类是否是接口 public native boolean isInterface(); // 判断当前的类是否是数组类 public native boolean isArray(); // 判断当前的类是否是注解类 public boolean isAnnotation() {}
2.Field类
概念:
Field,翻译过来就是字段,代表的是类的成员变量。
实例化方式:
//获取当前运行时类及其父类中声明为public访问权限的属性 Field[] fields = clazz.getFields(); for(Field f : fields){ System.out.println(f); } //获取当前运行时类中声明的所有属性。(不包含父类中声明的属性) Field[] declaredFields = clazz.getDeclaredFields(); for(Field f : declaredFields){ System.out.println(f); }
常用方法:
//获取权限修饰符(返回整理类型,java.lang.reflect.Modifier中有定义常量) int modifier = f.getModifiers(); System.out.println(modifier.toString()); //获取数据类型 Class type = f.getType(); String typename = type.getName(); //获取变量名 String name = f.getName(); // 设置对象obj对应的属性的值为value public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException {} // 获取对象obj对应的属性值 public Object get(Object obj)throws IllegalArgumentException, IllegalAccessException {}
3.Method类
概念:
Method,翻译过来就是方法的意思,代表的是类的成员方法。
实例化方式:
//获取当前运行时类及其所有父类中声明为public权限的方法 Method[] methods = clazz.getMethods(); for(Method m : methods){ System.out.println(m); } //获取当前运行时类中声明的所有属性。(不包含父类中声明的属性) Method[] declaredMethods = clazz.getDeclaredMethods(); for(Method m : declaredMethods){ System.out.println(m); }
常用方法:
//获取注解 Annotation[] annos = m.getAnnotations(); //获取权限修饰符 int modifier = m.getModifiers(); System.out.println(modifier.toString()); //获取返回值类型 m.getReturnType().getName(); //获取方法名(参数类型1 形参名1,....) String name = m.getName(); //获取方法中形参列表 Class[] parameterTypes= m.getParameterTypes(); if(!(parameterTypes == null && parameterTypes.length ==0)){ for(int i = 0;i < parameterTypes.length;i++){ System.out,println(parameterTypes[i].getName() + "args_" + i); } } //获取异常类型 Class[] exceptionTypes = m.getExceptionTypes();
4.Constructor类
概念:
Constructor,翻译过来就是构造函数的意思,代表的就是类的构造函数。
实例化方式:
//获取当前运行时类中声明为public的构造器 Constructor[] Constructors = clazz.getConstructors(); for(Constructor c : Constructors){ System.out.println(c); } //获取当前运行时类中声明的所有的构造器 Constructor[] declaredConstructors = clazz.getDeclaredConstructors(); for(Constructor c : declaredConstructors){ System.out.println(c); }
四,反射实例化对象的使用
1.运行时类给指定属性赋值
//创建运行时类的对象 Person p = (Person) clazz.newInstance(); //创建运行时类的属性的对象 Field name = clazz.getDeclaredField(name); //开放权限,保证访问 name.setAccessible(true); //给指定对象赋值 name.set(p,"Tom");
2.运行时类使用指定方法
//创建运行时类的对象 Person p = (Person) clazz.newInstance(); //创建运行时类的方法对象 Method show = Clazz.getDeclaredMethod(show,String.class) //开放权限,保证访问 show.setAccessible(true); //调用方法 Method.invoke(p,"方法需给的传参");
3.运行时类使用指定的构造器
//获取指定的构造器,并给定构造需要的属性的反射类 Construtor construtor = clazz.getDeclaredConstrutor(String.class); //开放权限,保证访问 construtor.setAccessible(true); //构造器调用方法创建运行时类的对象 Person per = construtor.newInstance("构造属性值");