一、簡介
java反射,在運行狀態時,對於任意一個類,都能知道這個類的屬性和方法。對於任意一個對象,都能夠調用方法和屬性。
反射是針對加載到JVM中的.class文件進行操作的,.class文件中包含了java類的所有信息。
對於java日常工作開發來說,反射可能平時接觸的很少,聽上去有點陌生卻又似曾相識。實際上,我們日常使用的各種框架中,很多都大量的運用反射機制去完成,
比如spring中,bean對象的管理上,就是運用了反射機制去生成bean。
二、API及樣例
使用反射的步驟:
1、獲得想要操作的類的java.lang.Class對象
2、調用操作的方法,比如getDeclaredMethods
3、使用反射api,來操作獲得信息,比如執行方法invoke
1 package com.cfang.reflect; 2 3 import java.math.BigDecimal; 4 5 public class MessageInfo { 6 7 private Integer msgId; 8 private String msg; 9 private BigDecimal total; 10 11 public String msg1; 12 private static final String msg2 = "123"; 13 14 /** 15 * 無參構造 16 */ 17 public MessageInfo() { 18 } 19 /** 20 * 有參構造 21 */ 22 public MessageInfo(Integer msgId, String msg, BigDecimal total) { 23 this.msgId = msgId; 24 this.msg = msg; 25 this.total = total; 26 } 27 /** 28 * private 有返回的無參方法 29 */ 30 private String calcMsg() { 31 return this.msg + this.total; 32 } 33 private int calcMsgTo(String inMsg, String title) { 34 return inMsg.length() + title.length(); 35 } 36 /** 37 * public 有返回的無參方法 38 */ 39 public String calcMsg1() { 40 return this.msg + this.total; 41 } 42 43 public Integer getMsgId() { 44 return msgId; 45 } 46 public void setMsgId(Integer msgId) { 47 this.msgId = msgId; 48 } 49 public String getMsg() { 50 return msg; 51 } 52 public void setMsg(String msg) { 53 this.msg = msg; 54 } 55 public BigDecimal getTotal() { 56 return total; 57 } 58 public void setTotal(BigDecimal total) { 59 this.total = total; 60 } 61 public String getMsg1() { 62 return msg1; 63 } 64 public void setMsg1(String msg1) { 65 this.msg1 = msg1; 66 } 67 }
測試main類
1 package com.cfang.reflect; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Field; 5 import java.lang.reflect.InvocationTargetException; 6 import java.lang.reflect.Method; 7 import java.math.BigDecimal; 8 9 public class TestMain { 10 11 public static void main(String[] args) throws Exception { 12 13 //獲取類對象 14 Class cls = Class.forName("com.cfang.reflect.MessageInfo"); 15 Class cls1 = MessageInfo.class; 16 Class cls2 = new MessageInfo().getClass(); 17 18 //獲取構造方法並實例化對象 19 //無參 20 Constructor constructor = cls.getConstructor(); 21 MessageInfo messageInfo = (MessageInfo) constructor.newInstance(); 22 23 Constructor constructor2 = cls.getDeclaredConstructor(); 24 MessageInfo messageInfo2 = (MessageInfo) constructor2.newInstance(); 25 //有參 26 Constructor constructor3 = cls.getConstructor(Integer.class, String.class, BigDecimal.class); 27 MessageInfo messageInfo3 = (MessageInfo) constructor3.newInstance(1,"hello world", BigDecimal.TEN); 28 29 Constructor constructor4 = cls.getDeclaredConstructor(Integer.class, String.class, BigDecimal.class); 30 MessageInfo messageInfo4 = (MessageInfo) constructor4.newInstance(1,"hello world", BigDecimal.TEN); 31 32 //實例化類對象 33 34 //私有方法,執行並獲取返回結果 35 Method method = cls.getDeclaredMethod("calcMsgTo", String.class, String.class); 36 // Method method = cls.getDeclaredMethod("calcMsgTo", new Class[] {String.class,String.class}); 37 method.setAccessible(true);//私有方法,屏蔽檢查,解除私有限定 38 int i = (int) method.invoke(messageInfo, "test", "eva"); //兩個參數:第一個要調用的對象(前面反射獲取),第二個是實參 39 // int i = (int) method.invoke(messageInfo, new String[]{"test", "eva"}); 40 System.out.println(i); 41 42 Method method2 = cls.getDeclaredMethod("calcMsg"); 43 method2.setAccessible(true);//私有方法,屏蔽檢查,解除私有限定 44 // method2.invoke(messageInfo3); 45 System.out.println(method2.invoke(messageInfo3)); 46 47 //public方法 48 Method method3 = cls.getDeclaredMethod("calcMsg1"); 49 // method2.invoke(messageInfo3); 50 System.out.println(method3.invoke(messageInfo2)); 51 52 //私有屬性獲取 53 Field field = cls.getDeclaredField("msg"); 54 field.setAccessible(true); 55 Object value = field.get(messageInfo4); 56 System.out.println(value); 57 System.out.println(field.getType()); 58 59 //public屬性 60 Field field1 = cls.getDeclaredField("msg1"); 61 field1.set(messageInfo4, "456"); //設值 62 Object value1 = field1.get(messageInfo4); 63 System.out.println(value1); 64 System.out.println(field1.getType()); 65 66 Field field2 = cls.getDeclaredField("msg2"); 67 field2.setAccessible(true); 68 Object value2 = field2.get(messageInfo4); 69 System.out.println(value2); 70 System.out.println(field2.getType()); 71 } 72 }