11、反射
反射很多框架设计的基础。通过获取的类class字节码类,从而得到类中所有的属性和方法,且可以调用,这种动态的获取和使用的功能就是java的反射机制。(我们所写类中的属性和方法都有对应的类来描述,反射就是获取这些组成类的不同成分的对象)
-
通过反射获取对象
//通过反射获取类的class对象,通过包+类名的方式获取 Class clazz = null; try { clazz = Class.forName("包路径+类名"); //获取类的全路径 clazz.getName(); //只获取类名 clazz.getSimpleName(); } catch (Exception e) { e.printStackTrace(); }
-
通过反射获取构造方法
//构造方法 try { System.out.println("===public的构造方法==="); Constructor[] constructors = clazz.getConstructors(); for(Constructor c : constructors){ System.out.println(c); } System.out.println("===所有的构造方法==="); Constructor[] declaredConstructors = clazz.getDeclaredConstructors(); for(Constructor c : declaredConstructors){ System.out.println(c); } System.out.println("===获取无参构造方法==="); Constructor constructor = clazz.getConstructor(null); System.out.println(constructor); System.out.println("===调用构造方法==="); System.out.println("===先获取有一个String的参数==="); Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class); System.out.println("参数为String类型的构造方法:"+declaredConstructor); declaredConstructor.setAccessible(true); //获取权限,可直接调用private修饰的方法 Persion p = (Persion)declaredConstructor.newInstance("张三"); //创建对象 System.out.println(p.getName()); } catch (Exception e) { e.printStackTrace(); }
-
通过反射获取属性
System.out.println("===获取public的属性==="); Field[] fields = clazz.getFields(); for(Field f :fields){ System.out.println(f); } System.out.println("===获取所有权限属性==="); Field[] declaredFields = clazz.getDeclaredFields(); for(Field f : declaredFields){ System.out.println(f); } System.out.println("===获取指定属性,并修改、获取值==="); try { Field f = clazz.getDeclaredField("name"); //("属性名") System.out.println(f); f.setAccessible(true); //可以获取private的使用权限 Object o = clazz.getConstructor().newInstance(); //反射创建对象 f.set(o ,"张三"); //反射修改值 System.out.println( f.get(o)); //反射获取值 } catch (Exception e) { e.printStackTrace(); } System.out.println("===获取属性的权限、类型、名字==="); for(Field f : declaredFields){ System.out.print(Modifier.toString(f.getModifiers())+" "); //权限 System.out.print(f.getType().getSimpleName()+" "); //类型 System.out.print(f.getName()); //名字 System.out.println(";"); }
-
通过反射获取方法
System.out.println("===获取所有public方法,包括父类继承的==="); Method[] methods = clazz.getMethods(); for(Method m : methods){ System.out.println(m); } System.out.println("===获取自定义的所有方法==="); Method[] declaredMethods = clazz.getDeclaredMethods(); for(Method m : declaredMethods){ System.out.println(m); } System.out.println("===获取方法的权限修饰符、返回值、方法名、参数类型==="); for(Method m : declaredMethods){ System.out.print(Modifier.toString(m.getModifiers())+" "); //权限修饰符 System.out.print(m.getReturnType().getSimpleName()+" "); //返回值 System.out.print(m.getName()); //方法名 Parameter[] parameters = m.getParameters(); //参数类型数组,需遍历 System.out.print("("); for(Parameter p : parameters){ System.out.print(p.getType().getSimpleName()+","); } System.out.println(");"); } System.out.println("===获取指定方法并调用==="); try { //获取名为getName的方法,无参数传递 Method getName = clazz.getMethod("getName", null); System.out.println(getName); getName.setAccessible(true); //可以获取private的使用权限 //获取名为setName的方法,传递的参数类型为String Method setName = clazz.getMethod("setName", String.class); System.out.println(setName); setName.setAccessible(true); //可以获取private的使用权限 //创建一个对象 Object o = clazz.getConstructor().newInstance(); //反射调用setName方法 setName.invoke(o,"张三"); //反射调用getName方法 System.out.println(getName.invoke(o)); } catch (Exception e) { e.printStackTrace(); }