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 對象表示的底層方法。