講到java反射機制,咱們就須要先講一下動態語言的概念,都知道java是一門強類型語言,而動態語言就是在程序的運行期間對屬性的類型進行改變,和狀態的獲取,如(python,javascript)。因此,java就須要利用反射機制在程序的運行狀態中,將一個類的全部成分(屬性,構造器,方法)反射成相對應的類。同時對於任意一個對象,咱們能夠調用它的任意個方法和屬性,這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。javascript
//得到類對象 Class clz = Class.forName("edu.hubu.dto.People"); //得到實例 Object obj = clz.newInstance();
/獲取當前類中的全部註解 Annotation[] ans = clz.getAnnotations(); for (Annotation annotation : ans) { //System.out.println(annotation); }
//得到公有的構造器(public) Constructor[] constructs = clz.getConstructors(); for (Constructor constructor : constructs) { //System.out.println(constructor); } //得到指定類中全部構造器 constructs = clz.getDeclaredConstructors(); for (Constructor constructor : constructs) { //System.out.println(constructor); }
//得到指定類中全部公有的屬性(public) Field[] fields = clz.getFields(); for (Field field : fields) { //System.out.println(field); } //得到全部的屬性對象 fields = clz.getDeclaredFields(); for (Field field : fields) { System.out.println(field); //得到屬性名稱 field.getName(); //得到屬性類型 field.getType(); //得到屬性修飾符 field.getModifiers(); }
//獲取全部公有方法(public) Method[] methods =clz.getMethods(); //獲取全部方法 methods = clz.getDeclaredMethods(); for (Method method : methods) { //獲取方法的返回值類型 method.getReturnType(); //獲取方法的參數列表 Class[] types = method.getParameterTypes(); }
public String eat(int age ,String name,String food){ return age + "歲的" + name + "在吃:" + food; }
- 通常咱們會構建一個People實例而後調用這個方法,下面咱們採用反射的方式調用這個方法
//根據給定的方法名和方法執行須要的參數類型集合得到一個Method對象 Method method = clz.getMethod("eat", new Class[]{int.class,java.lang.String.class,java.lang.String.class}); //根據method的invoke方法來執行指定類中的eat方法(obj-》指定類的實例,Object[]是參數的值) Object o = method.invoke(obj, new Object[]{18,"jack","龍蝦"});
###4. 利用java反射機制,實現對象的拷貝java
public class People { public int pid; public String pname; private int age; private double sal; public People(){ } public People(int pid, String pname, int age, double sal) { super(); this.pid = pid; this.pname = pname; this.age = age; this.sal = sal; } public People(int pid, String pname) { super(); this.pid = pid; this.pname = pname; } public int getPid() { return pid; } public void setPid(int pid) { this.pid = pid; } public String getPname() { return pname; } public void setPname(String pname) { this.pname = pname; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } public String eat(int age ,String name,String food){ return age + "歲的" + name + "在吃:" + food; } }
//目標對象 People p = new People(1,"張三",18,5000); Object newObj = new ObjectClone().copy(p); //副本對象 People p2 = (People)newObj;
target.getClass().getName()
- 得到類路徑以後,咱們即可以獲取類對象,以及得到實例
Class clz = Class.forName(target.getClass().getName()); newObj = clz.newInstance();
- 而後,咱們應該得到類的全部屬性,而後根據屬性獲取setter/getter方法
//得到類屬性 Field[] fields = clz.getDeclaredFields(); /** * 根據對象屬性獲取setter/getter方法 */ for (Field f : fields) { //獲取屬性名 String fieldName = f.getName(); //獲取getter方法的方法名 String getMethodName = "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1); //獲取getter方法對象 Method method_get = clz.getMethod(getMethodName,new Class[]{}); //獲取setter方法的方法名 String setMethodName = "set" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1); //獲取setter方法對象 Method method_set = clz.getMethod(setMethodName,new Class[]{f.getType()}); //執行目標類的get方法獲取返回值 Object returnValue = method_get.invoke(target, new Object[]{}); //執行setter方法爲新對象賦值 method_set.invoke(newObj, new Object[]{returnValue});
public class ObjectClone { public Object copy(Object target){ Object newObj = null; try { Class clz = Class.forName(target.getClass().getName()); newObj = clz.newInstance(); //得到類屬性 Field[] fields = clz.getDeclaredFields(); /** * 根據對象屬性獲取setter/getter方法 */ for (Field f : fields) { //獲取屬性名 String fieldName = f.getName(); //獲取getter方法的方法名 String getMethodName = "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1); //獲取getter方法對象 Method method_get = clz.getMethod(getMethodName,new Class[]{}); //獲取setter方法的方法名 String setMethodName = "set" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1); //獲取setter方法對象 Method method_set = clz.getMethod(setMethodName,new Class[]{f.getType()}); //執行目標類的get方法獲取返回值 Object returnValue = method_get.invoke(target, new Object[]{}); //執行setter方法爲新對象賦值 method_set.invoke(newObj, new Object[]{returnValue}); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return newObj; } public static void main(String[] args) { //目標對象 People p = new People(1,"張三",18,5000); Object newObj = new ObjectClone().copy(p); //副本對象 People p2 = (People)newObj; System.out.println(p2.getPid()+"\t"+p2.getPname()); } }