Java反射涉及的几个类分别为Class,Filed,Methods,Constructor,Modifier,AccessibleObject的几个类。java
咱们定义一个 Employee类web
package util; import java.util.Date; import java.util.GregorianCalendar; public class Employee { private String name; private double salary; private Date hireDay; public Employee(String n, double s, int year, int month, int day) { name = n; salary = s; GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day); hireDay = calendar.getTime(); } public String getName() { return name; } public double getSalary() { return salary; } public Date getHireDay() { return hireDay; } public void raiseSalary(double byPercent) { double raise = salary * byPercent / 100; salary += raise; } }
Employee为一个类,而代码apache
Employee harry=new Employee("Harry Hacker",3500,10,1,1989);
定义了一个 对象harry, 类Employee用来描述 对象harry的信息,而Java虚拟机在运行的时候须要一个类来描述 类Employee的信息,这个类就是 Class,称之为 类型,能够用来获取一个类的全部域 Field,构造器 Constructor,方法 Method。 反射的两个很重要的两个能力。分析一个类和执行任意方法。数组
package util; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Scanner; import org.apache.commons.lang3.StringUtils; public class ReflectionTest { public static void main(String[] args) { String name; if (args.length > 0) { name = args[0]; } else { Scanner scanner = new Scanner(System.in); name = scanner.nextLine(); } try { Class cl = Class.forName(name); Class supercl = cl.getSuperclass(); String modifier = Modifier.toString(cl.getModifiers()); if (modifier != null && modifier.length() > 0) { System.out.print(modifier + " "); } System.out.print("class " + name); Double aDouble = 0.0; if (supercl != null && supercl != Object.class) { System.out.print(" extends " + supercl.getName()); } System.out.print("\n{\n"); printConstructors(cl); printMethods(cl); printFields(cl); System.out.print("}\n"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //打印构造函数 public static void printConstructors(Class cl) { Constructor[] constructors = cl.getDeclaredConstructors(); for (Constructor constructor : constructors) { String name = constructor.getName(); String modifier = Modifier.toString(constructor.getModifiers()); System.out.print(" "); // System.out.print(modifier+" "+name+"("); if (modifier!=null&&modifier.length()>0) { System.out.print(modifier+" "); } System.out.print(name+" ("); Class[] paraTypes=constructor.getParameterTypes(); for(int i=0;i<paraTypes.length;i++){ if (i>0) { System.out.print(","); } System.out.print(paraTypes[i].getName()); } System.out.println(");"); } } //打印成员变量 public static void printFields(Class cl){ Field[] fields=cl.getDeclaredFields(); for (Field field : fields) { String modifier=Modifier.toString(field.getModifiers()); Class type=field.getType(); String name=field.getName(); System.out.print(" "); if (modifier.length()>0) { System.out.print(modifier+" "); } System.out.println(type.getName()+" "+name+";"); } } //打印方法名 public static void printMethods(Class cl){ Method[] methods=cl.getDeclaredMethods(); for (Method method : methods) { String name=method.getName(); String modifier=Modifier.toString(method.getModifiers()); System.out.print(" "); if (modifier.length()>0) { System.out.print(modifier+" "); } System.out.print(method.getName()+"("); Class[] paraTypes=method.getParameterTypes(); for(int i=0;i<paraTypes.length;i++){ if (i>0) { System.out.print(","); } System.out.print(method.getName()); } System.out.println("};"); } } }
package study_web; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class MethodTest { public static void main(String[] args) { /*System.out.println(Math.sqrt(4));*/ try { Class cl=Class.forName("java.lang.Math"); try { Method method=cl.getDeclaredMethod("sqrt", double.class); /*Class returnType=method.getReturnType();*/ Double value=(Double) method.invoke(null, 4.0); System.out.println(value); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
在这个demo中咱们用反射执行了Math.sqrt方法函数
package study_web; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import util.Employee; public class ReflectTest { public static void main(String[] args) { Employee harry=new Employee("Harry Hacker",3500,10,1,1989); Class cl=harry.getClass(); try { Field field=cl.getDeclaredField("name"); /*AccessibleObject[] array=new AccessibleObject[]{field}; AccessibleObject.setAccessible(array, true);*/ field.setAccessible(true); field.set(harry, "li yuahng"); System.out.println(harry.getName()); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }
由于Java反射默认听从Java访问权限控制,因此咱们能够使用代码:code
AccessibleObject[] array=new AccessibleObject[]{field}; AccessibleObject.setAccessible(array, true);
或者代码:对象
field.setAccessible(true);
使得Field域可被访问。继承
返回描述类名className的Class对象接口
返回这个类的新实例字符串
getFields方法返回一个包含Field对象的数组,这些对象记录了这个类或其它超类的公有域。getDeclaredFields方法也将返回包含Field对象的数组,这些对象记录了这个类的所有域。若是类中没有域,或者Class对象描述的是基本类型或者数据类型,这些方法将返回一个长度为0的数组
返回包含 Method对象的数组:getMethods将返回全部的公有方法,包括从超类继承来的公有方法;getDeclaredMethods返回这个类或接口的的所有方法,但不包括由超类继承来的方法。
同上,不作解释
返回一个用于描述构造器、方法、域的修饰符的整型数值。使用Modifier类中的这个方法能够分析这个返回值。
###java.lang.reflect.Modifier
返回modifiers中位设置的修饰符的字符串表示
为反射对象设置可访问标志。flag为true,代表屏蔽Java语言的访问检查,使得对象的私有属性也能够被查询和设置
返回反射对象可访问标志的值
是一种设置对象数组可访问标志的快捷方法
用一个新值设置obj对象中Field对象表示的域
对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。