1、先来一个最简单的。通过反射得到方法、字段
import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.Test; public class Reflect1 { @Test public void getMethods() throws Exception{ //得到所有(自己类中)的方法,包括private的方法 Class<?> strClazz = Class.forName("java.lang.String"); Method[] declaredMethods = strClazz.getDeclaredMethods(); for(Method method : declaredMethods){ System.out.println(method.getName()); } } @Test public void getFields() throws Exception{ //得到所有(自己类中)的字段,包括private的字段 Class<?> strClazz = Class.forName("java.lang.String"); Field[] declaredFields = strClazz.getDeclaredFields(); for(Field field : declaredFields){ System.out.println(field.getName()); } } }
2、通过反射调用方法
import java.lang.reflect.Method; import org.junit.Test; /** * 通过反射调用方法 * @author Administrator * */ public class Reflect2 { public Integer add(int num1 , int num2){ return num1 + num2; } public String say(String name){ return "hello "+name; } public String print(String str){ return str; } public String print(){ return "hello world"; } /** * 传统方式 * @description * @Date Jul 21, 2017 */ @Test public void ordinaryTest(){ Reflect2 r2 = new Reflect2(); r2.add(1, 2); r2.say("张三"); r2.print("hello world"); } /** * 通过反射调用方法 * @description * @Date Jul 21, 2017 */ @Test public void reflectTest() throws Exception{ Class<?> clazz = Reflect2.class; //得到class Reflect2 reflect2 = (Reflect2) clazz.newInstance(); //得到新的对象 Method addMmethod = clazz.getMethod("add", new Class[]{int.class,int.class}); Integer addResult = (Integer) addMmethod.invoke(reflect2, 1,3); System.out.println(addResult); System.out.println("----------------------------"); Method sayMethod = clazz.getMethod("say", new Class[]{String.class}); Object invoke = sayMethod.invoke(reflect2, "张三"); System.out.println(invoke); System.out.println("----------------------------"); Method printMethod = clazz.getMethod("print", new Class[]{String.class}); Object invoke2 = printMethod.invoke(reflect2, "hello world"); System.out.println(invoke2); System.out.println("----------------------------"); Method printMethod2 = clazz.getMethod("print", new Class[]{}); Object invoke3 = printMethod2.invoke(reflect2); System.out.println(invoke3); } }
3、通过反射访问私有属性、方法
首先有个类
public class TestClass { private String name; public String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } private String say(){ return "hello world"; } private String say(String name){ return "hello "+name; } public String say2(){ return "hello world"; } public String say2(String name){ return "hello "+name; } }
接着 通过反射访问上边类中的方法属性(包括私有方法属性)
import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.Test; /** * 反射访问私有方法,私有属性 * @author Administrator * */ public class Reflect4 { /** * 访问 public方法 * @description * @Date Jul 21, 2017 * @throws Exception */ @Test public void getPublicMethod() throws Exception{ Class<?> clazz = TestClass.class; Object obj = clazz.newInstance(); Method method1 = clazz.getDeclaredMethod("say2"); Object value1 = method1.invoke(obj); System.out.println(value1); System.out.println("------------------------"); Method method2 = clazz.getDeclaredMethod("say2",new Class[]{String.class}); Object value2 = method2.invoke(obj, "张三"); System.out.println(value2); } /** * 访问私有方法 * @description * @Date Jul 21, 2017 * @throws Exception */ @Test public void testGetPrivateMethod() throws Exception{ Class<?> clazz = TestClass.class; TestClass obj = (TestClass) clazz.newInstance(); Method method1 = clazz.getDeclaredMethod("say"); method1.setAccessible(true); // 访问私有方法,如果不设置 会报错 java.lang.IllegalAccessException: Class com.test.reflect.Reflect4 can not access // a member of class com.test.reflect.TestClass with modifiers "private" Object value1 = method1.invoke(obj); System.out.println(value1); System.out.println("---------------------"); Method method2 = clazz.getDeclaredMethod("say",new Class[]{String.class}); method2.setAccessible(true); Object value2 = method2.invoke(obj, "张三"); System.out.println(value2); System.out.println("---------------------"); } /** * 访问public 属性 * @description * @Date Jul 21, 2017 * @throws Exception */ @Test public void testGetPublicField() throws Exception{ Class<?> clazz = TestClass.class; TestClass obj = (TestClass) clazz.newInstance(); Field declaredField = clazz.getDeclaredField("address"); declaredField.set(obj, "济南"); System.out.println(obj.getAddress()); } /** * 访问private属性 * @description * @Date Jul 21, 2017 * @throws Exception */ @Test public void testGetPrivateField() throws Exception{ Class<? extends Object> clazz = TestClass.class; TestClass obj = (TestClass) clazz.newInstance(); Field declaredField = clazz.getDeclaredField("name"); declaredField.setAccessible(true); // 访问私有属性,不设置会报错 java.lang.IllegalAccessException: Class com.test.reflect.Reflect4 can not access // a member of class com.test.reflect.TestClass with modifiers "private" declaredField.set(obj, "张三"); System.out.println(obj.getName()); } }
4、clazz.getMethods 和clazz.getDeclaredMethods的不同
另建一个类,继承 TestClass
public class TestClass2 extends TestClass{ private String testSay(){ return "hello world"; } public String testSay2(){ return "hello world"; } }
测试不同
/** * clazz.getMethods 和clazz.getDeclaredMethods的不同 * @description * @Date Jul 21, 2017 */ @Test public void testDifferent(){ Class<?> clazz = TestClass2.class; Method[] methods = clazz.getMethods(); // 取出本类中非private的方法。同时会把 父类(父类的父类,父类的父类的父类,。。。)中的方法(不包括private)也取出来 for(Method method : methods){ System.out.println(method.getName()); } System.out.println("-----------------------------"); Method[] declaredMethods = clazz.getDeclaredMethods(); // 自己定义的类中的所有的方法 for(Method method : declaredMethods){ System.out.println(method.getName()); } }
通过结果可以看出
clazz.getMethods(); // 取出本类中非private的方法。同时会把 父类(父类的父类,父类的父类的父类,。。。)中的方法(不包括private)也取出来。
而clazz.getDeclaredMethods(); // 自己定义的类中的所有的方法。
5、反射的简单应用,利用反射复制一个对象
首先创建一个两类。Child 和 ChildBean。利用反射将Child 复制为 ChildBean
Child类
public class Child { private Integer id; private String name; private Integer age; private String address; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Child [id=" + id + ", name=" + name + ", age=" + age + ", address=" + address + "]"; } }
ChildBean 类
public class ChildBean { private Integer id; private String name; private Integer age; private String address; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "ChildBean [id=" + id + ", name=" + name + ", age=" + age + ", address=" + address + "]"; } }
利用反射复制
import java.lang.reflect.Field; import java.lang.reflect.Method; import org.apache.commons.lang.StringUtils; import org.junit.Test; /** * 利用反射,复制 * @author Administrator * */ public class Reflect3 { // obj ---> newClazz public <T> T copyByReflect(Object obj, Class<T> newClazz) throws Exception{ T newObj = newClazz.newInstance(); Class<?> objClazz = obj.getClass(); Field[] objFields = objClazz.getDeclaredFields(); Field[] newFields = newClazz.getDeclaredFields(); if(newFields.length > 0 && objFields.length >0){ for(Field newField : newFields){ String newFieldName = newField.getName(); for(Field objField : objFields){ String objFieldName = objField.getName(); if(objFieldName.equals(newFieldName)){ String upperFieldName = StringUtils.capitalize(objFieldName); //capitalize 首字母大写(如: name---> Name, id--->Id) // get obj field value Method getGetMethod = objClazz.getMethod("get"+upperFieldName); Object value = getGetMethod.invoke(obj); // set newObj field value Method getSetmethod = newClazz.getMethod("set"+upperFieldName, objField.getType()); getSetmethod.invoke(newObj, value); } } } } return newObj; } @Test public void testMain() throws Exception{ Child child = new Child(); child.setAddress("山东"); child.setAge(18); child.setId(1); child.setName("张三"); System.out.println("child:"+child); ChildBean newChild = this.copyByReflect(child, ChildBean.class); System.out.println("childBean:"+newChild); } }