1. Start with the easiest one. Get methods and fields through reflection
import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.Test; public class Reflect1 { @Test public void getMethods() throws Exception{ //Get all methods (in your own class), including private methods 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{ //Get all fields (in your own class), including private fields Class<?> strClazz = Class.forName("java.lang.String"); Field[] declaredFields = strClazz.getDeclaredFields(); for(Field field : declaredFields){ System.out.println(field.getName()); } } }
2. Calling methods through reflection
import java.lang.reflect.Method; import org.junit.Test; /** * Call the method by reflection * @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"; } /** * Traditional way * @description * @Date Jul 21, 2017 */ @Test public void ordinaryTest(){ Reflect2 r2 = new Reflect2(); r2.add(1, 2); r2.say("Zhang San"); r2.print("hello world"); } /** * Call the method by reflection * @description * @Date Jul 21, 2017 */ @Test public void reflectTest() throws Exception{ Class<?> clazz = Reflect2.class; //得到class Reflect2 reflect2 = (Reflect2) clazz.newInstance(); //Get a new object 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. Access private properties and methods through reflection
First there is a class
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; } }
Then access the method properties (including private method properties) in the above class through reflection
import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.Test; /** * Reflective access to private methods, private properties * @author Administrator * */ public class Reflect4 { /** * Access public methods * @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); } /** * access private methods * @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); // Access to private methods, if not set, an error will be reported 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("---------------------"); } /** * access public properties * @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, "Jinan"); System.out.println(obj.getAddress()); } /** * Access private properties * @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); // Accessing private properties, if not set will report an error 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, "Zhang San"); System.out.println(obj.getName()); } }
4. The difference between clazz.getMethods and clazz.getDeclaredMethods
Create another class that inherits from TestClass
public class TestClass2 extends TestClass{ private String testSay(){ return "hello world"; } public String testSay2 () { return "hello world"; } }
test different
/** * Difference between clazz.getMethods and clazz.getDeclaredMethods * @description * @Date Jul 21, 2017 */ @Test public void testDifferent(){ Class<?> clazz = TestClass2.class; Method[] methods = clazz.getMethods(); // Take out the non-private methods in this class. At the same time, the methods (excluding private) in the parent class (the parent class of the parent class, the parent class of the parent class, ...) will also be taken out. for(Method method : methods){ System.out.println(method.getName()); } System.out.println("-----------------------------"); Method[] declaredMethods = clazz.getDeclaredMethods(); // all methods in the class defined by yourself for(Method method : declaredMethods){ System.out.println(method.getName()); } }
It can be seen from the results
clazz.getMethods(); // Take out the non-private methods in this class. At the same time, the methods (excluding private) in the parent class (the parent class of the parent class, the parent class of the parent class, ...) will also be taken out.
And clazz.getDeclaredMethods(); // All the methods in the class defined by yourself.
5. Simple application of reflection, use reflection to copy an object
First create a two class. Child and ChildBean. Copy Child as ChildBean using reflection
Child class
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 class
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 + "]"; } }
Copy using reflection
import java.lang.reflect.Field; import java.lang.reflect.Method; import org.apache.commons.lang.StringUtils; import org.junit.Test; /** * Use reflection, copy * @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 capitalize the first letter (eg: 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("Shandong"); child.setAge(18); child.setId(1); child.setName("Zhang San"); System.out.println("child:"+child); ChildBean newChild = this.copyByReflect(child, ChildBean.class); System.out.println("childBean:"+newChild); } }