java通過反射獲取並調用對象方法探究

package test;
/**
 * 測試類
 */
public class TestService {
	
	public String testMethod(){
		return "success test method";
	}

	private String testMethod(String param){
		return "success test method param = " +param;
	}

	public String testMethod(String param1,String param2){
		return "success test method param1 = " +param1 + " param2="+param2;
	}
	
	public String testMethod(String param1,int param2){
		return "success test method param1 = " +param1 + " param2="+param2;
	}

}
package test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.junit.Test;

public class TestController {
	@Test
	public void testField() {
	    try {
	    	//根據類名獲取所需類
			Class<?> clazz = Class.forName("test.TestService");
			//實例化對象
			Object a = clazz.newInstance();
			//獲取對象中的所有方法,包括私有方法
	    	Method[] methods = clazz.getDeclaredMethods();
		    for (Method method : methods) {
		    	//獲取方法所需參數個數以及類型
		        Object[] objs = null;
		        if (method.getParameterTypes().length>0) {
		        	objs = new Object[method.getParameterTypes().length];
		        	int index = 0;
		        	for (Object parameterType : method.getParameterTypes()) {
		        		if (parameterType==String.class) {
		        			objs[index++] = "a";
						}else if (parameterType==Integer.class||parameterType==int.class) {
						//可擴展爲是否是數字類型
		        			objs[index++] = 1;
						}
					}
				}
				//這裏需要注意。檢查方法是否爲private,如果是需要設置方法的accessible
				//否則會發生異常 java.lang.IllegalAccessException: Class test.TestController can not access a member of class test.TestService with modifiers "private"
				//accessible 值爲 true 則指示反射的對象在使用時應該取消 Java 語言訪問檢查。值爲 false 則指示反射的對象應該實施 Java 語言訪問檢查。
		        if (Modifier.isPrivate(method.getModifiers())) {
					method.setAccessible(true);
				}
				//攜帶請求參數,否則會發生異常 java.lang.IllegalArgumentException: wrong number of arguments
		        Object o = method.invoke(a,objs);
		        System.out.println(o);
		    }
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

#輸出結果
success test method param1 = a param2=1
success test method param1 = a param2=a
success test method param = a
success test method

以上是反射對象中不存在注入的情況下可以使用的方法,一旦涉及到注入的時候,直接使用clazz.newInstance()會導致原本對象中注入的內容變爲空值,這裏需要通過spring去獲取對象bean。

package test;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class TestController {
	
	@Test
	public void testField() {
	    try {
			//初始化spring
	    	ApplicationContext ac = new ClassPathXmlApplicationContext(new String[] { "spring-test.xml" });
			Class<?> clazz = Class.forName("test.TestService");
			//獲取bean而不是直接創建實例
			Object a = ac.getBean(clazz);
//			Object a = clazz.newInstance();
	    	Method[] methods = clazz.getDeclaredMethods();
		    for (Method method : methods) {
		        Object[] objs = null;
		        if (method.getParameterTypes().length>0) {
		        	objs = new Object[method.getParameterTypes().length];
		        	int index = 0;
		        	for (Object parameterType : method.getParameterTypes()) {
		        		if (parameterType==String.class) {
		        			objs[index++] = "a";
						}else if (parameterType==Integer.class||parameterType==int.class) {//可擴展爲是否是數字類型
		        			objs[index++] = 1;
						}
					}
				}
		        if (Modifier.isPrivate(method.getModifiers())) {
					method.setAccessible(true);
				}
		        Object o = method.invoke(a,objs);
		        System.out.println(o);
		    }
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
}
<!-- 對應的spring-test.xml文件 -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-4.0.xsd">
	<!-- 配置要掃描的包 -->
	<context:component-scan base-package="test"></context:component-scan>
</beans>
#輸出結果
success test method param1 = a param2=1
success test method param1 = a param2=a
success test method param = a
test auto wired
success test method
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章