一、简介
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 }