Java operates classes through reflection

First, use the native reflection method

1. Create a new ordinary java class - Student

public class Student{
	private String userName;
	private String passWord;
	
	public Student(){}
	
	public Student(String userName,String passWord){
		this.userName = userName;
		this.passWord = passWord;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassWord() {
		return passWord;
	}
	public void setPassWord(String passWord) {
		this.passWord = passWord;
	}
	@Override
	public String toString() {
		return "Student [userName=" + userName + ", passWord=" + passWord + "]";
	}

2. Get all the methods in the class through the reflection method - getDeclaredMethods()

Note: Get all methods in the class through getDeclaredMethods, including public, protected, default (package) access and private methods, of course excluding its inherited methods (such as the methods in Student's implicitly inherited class Object); get all methods through getMethods Public (public) methods include public methods of their inherited classes (that is, methods in the parent class Object)

 

Class<?> clazz = null;
try {
	clazz = Class.forName("com.maps.test.proxy.Student");
} catch (ClassNotFoundException e) {
	e.printStackTrace ();
}
Method[] methods = clazz.getDeclaredMethods();
for(int i=0;i<methods.length;i++){
	Method method = methods[i];
	
	Parameter[] parameters = method.getParameters();
	StringBuilder sbf = new StringBuilder("(");
	for(int m=0;m<parameters.length;m++){
		Parameter parameter = parameters[m];
		String parameterName = parameter.getName();
		int modify = parameter.getModifiers();
		String parameterModify = Modifier.toString(modify);
		String parameterType =
                parameter.getType().getSimpleName();
		sbf.append(parameterModify).append("
                ").append(parameterType).append("
                ").append(parameterName).append(",");
	}
	if(sbf.lastIndexOf(",")>=0){
		sbf.deleteCharAt(sbf.length()-1);	
	}
	sbf.append(")");
	System.out.println("[methodInfo:{methodName:"+method.getName()+",returnType:"
        +method.getReturnType().getName()+"}"+",parameterInfo:{"+sbf.toString()+"}]");
}

 The result of running the above code - output the access permission, type, name information of each method and parameters in the method

 

[methodInfo:{methodName:toString,returnType:java.lang.String,methodModify:public},parameterInfo:{()}]
[methodInfo:{methodName:setUserName,returnType:void,methodModify:public},parameterInfo:{( String arg0)}]
[methodInfo:{methodName:setPassWord,returnType:void,methodModify:public},parameterInfo:{( String arg0)}]
[methodInfo:{methodName:getPassWord,returnType:java.lang.String,methodModify:public},parameterInfo:{()}]
[methodInfo:{methodName:getUserName,returnType:java.lang.String,methodModify:public},parameterInfo:{()}]

 

3. Get all the properties in the class through the reflection method - getDeclaredFields()

Note: The getDeclaredFields method is used to obtain all the properties in the class, including public, private and protected, default, but does not include the properties in the parent class; the getFields method obtains all the public (public) fields in the class, including the parent class properties declared in

 

Field[] fields = clazz.getDeclaredFields();
for(int i=0;i<fields.length;i++){
	Field field = fields[i];
	String fieldName = field.getName();//获取属性的名称
	Class<?> fieldType = field.getType();//获取属性的类型
	String fieldTypeValue = fieldType.getSimpleName(); //获取属性的简单
        类型,即不带java.lang前缀
	int modify = field.getModifiers();//获取数学的访问权限
	String modifyVal = Modifier.toString(modify);
	System.out.println("[fieldInfo:{fieldModify:"+modifyVal+",fieldType
        :"+fieldTypeValue+",fieldName:"+fieldName+"}]");
}

 

以上代码运行结果-输出了Student类中定义的两个属性

[fieldInfo:{fieldModify:private,fieldType:String,fieldName:userName}]
[fieldInfo:{fieldModify:private,fieldType:String,fieldName:passWord}]

 

 4. 通过反射调用类中的方法

 

/**
 * 通过类路径加载类Student
 */
Class<?> clazz = null;
try {
	clazz = Class.forName("com.maps.test.proxy.Student");
} catch (ClassNotFoundException e) {
	e.printStackTrace();
}
try {
	//实例化Studnt对象
	Object obj = clazz.newInstance();
	//Get the method in Student named setUserName, the number of parameters is only one, the parameter type
        Method body for String
	Method setUserNameMethod =
        clazz.getMethod("setUserName",String.class);
	//Call the setUseName method in the Student object through reflection invoke, and pass the parameters
        Number “maps”
	setUserNameMethod.invoke(obj,"maps");
	
	/**
	 * Directly modify the attribute value in Student
	 */
	Field field = clazz.getDeclaredField("userName");//Get the name in Studnt
        property called userName
        field.setAccessible(true);//Set the accessibility of the property
        field.set(obj, "mapingsheng");//Then set the value of this property
        for "mapingsheng"
	
	/**
	 * Call the getUserName method through reflection to get the attribute set in the previous step - userName
        value
	 */
	Method getUserNameMethod = clazz.getMethod("getUserName");
	String userNameValue = (String)
        getUserNameMethod.invoke(obj);
	System.out.println(userNameValue);
} catch (Exception e) {
	e.printStackTrace ();
}
  The result of running the above code:

 

mapingsheng

Second, use the java dynamic proxy-InvocationHandler method

Proxy is an application mode in which methods of real objects are indirectly invoked through intermediate proxy objects. In java, the java.lang.reflect API provides an API that provides proxy classes and InvocationHandler interfaces to implement dynamic proxy operations. The Proxy class creates a dynamic proxy class based on the given parameters. InvocationHandler invokes methods of dynamic proxy classes. All of these situations are discussed in detail below:

  • java.lang.reflect.Proxy is a class that provides static methods to create dynamic proxy classes. There is a newProxyInstance() method in the Proxy class defined as follows:
public static Object newProxyInstance (ClassLoader loader ,Class <?> []
interfaces ,InvocationHandler h)
 The meaning of the three parameters in this method:

 

ClassLoader: This class loader will define dynamic proxy classes. The class loader can be obtained by the class or interface whose dynamic proxy is being created.

interfaces: The second parameter is an array of all interfaces implemented by the proxied class

InvocationHandler: The third parameter is to pass an instance of a class that implements java.lang.reflect.InvocationHandler

  • InvocationHandler in java is an interface in java.lang.reflect package. The InvocationHandler is implemented by the user class to invoke the methods of the dynamic proxy class. The syntax of the invoke method is as follows
  • Object invoke(Object proxy ,Method m ,Object [] args)
  • The meaning of the three parameters in this method:

    Object: This is the proxy instance on which the method is invoked.

    Method: This corresponds to the interface method invoked on the proxy instance.

    Object[]: It contains an array of parameters passed in the method call.

    - Use the code to demonstrate the dynamic proxy operation of java

    通过一个结婚的场景来模拟动态代理场景,比如日常生活中要结婚的话,需要预定场地和吃饭的酒店,并且出行需要预定汽车服务。

    • 一个代理结构(中介)提供了很多套餐(酒店+出行套餐、酒店+婚礼主持+出行套餐等等)–代理类MarryProxy
    • 这个代理机构提供了很多套餐服务,一般开发中都是面向接口编程(MarryPackageService、MarryPackageServiceImpl)
    • 我们采取最经济的套餐(酒店+出行套餐)来讲,可以看到上面场景一共需要提供如下类:
      1. 定义一个结婚套餐服务接口
        /**
         * 结婚套餐(提供酒店+出行服务)
         * @author mapingsheng
         */
        public interface MarryPackageService {
        	
        	/**
        	 * 提供酒店服务,一站式解决婚礼举办、就餐问题
        	 * @return
        	 */
        	public String hotel(String address,String hotelName);
        	/**
        	 * 提供用车服务,解决出行问题
        	 * @return
        	 */
        	public String car(String carName);
        }
         
      2. 定义一个结婚套餐接口的实现类
        /**
         * 结婚套餐(提供酒店+出行服务)具体业务类
         * @author mapingsheng
         */
        public class MarryPackageServiceImpl implements
      3.  MarryPackageService{
        	@Override
        	public String hotel(String address, String hotelName) {
        		Date date = new Date();
        		SimpleDateFormat sf = new SimpleDateFormat
      4.                ("yyyy-MM-dd HH:mm:ss");
        		
        		return sf.format(date)+" 【"+address+" "+hotelName+"
      5.               】 提
                        供就餐服务";
        	}
        	@Override
        	public String car(String carName) {
        		return "【"+carName+"】  提供出行服务";
        	}
        }
         
      6. 定义一个代理结构-代理类

    注:代理类必须实现InvocationHandler接口,我们在构造方法中初始化被代理的对象

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    public class MarryProxy implements InvocationHandler{
    	private Object obj;//这个就是我们要代理的真实对象
    	
    	/**
    	 * 通过构造函数初始化代理对象
    	 * @param obj
    	 */
    	public  MarryProxy(Object obj){
    		 this.obj = obj;
    	 }
    	/**
    	 * 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联
  • 的handler对象的invoke方法来进行调用
    	 */
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args)
  •         throws Throwable {
    		return method.invoke(obj, args);
    	}
    }
  • import java.lang.reflect.InvocationHandler;
    1. 新建一个测试类
      import java.lang.reflect.Proxy;
      public class MarryClient {
      	public static void main(String[] args) {
      	//我们要代理的真实对象
    2. MarryPackageService marryPackageService =
    3.  new MarryPackageServiceImpl();
      		//初始化代理类
         InvocationHandler handler = new MarryProxy(marryPackageService);
         //通过Proxy的newProxyInstance方法来创建我们的代理对象
         Object obj = Proxy.newProxyInstance(marryPackageService.getClass
    4.    ().getClassLoader(), 											marryPackageService.getClass().getInterfaces(), 									handler);
       MarryPackageService marryService = (MarryPackageService) obj;
       String hotelInfo = marryService.hotel("北京市海淀区中关村南大街8号",
    5.  "香格里拉大酒店");
      String carInfo = marryService.car("奥迪A6");
      System.out.println(hotelInfo+" "+carInfo);
      	}
      }
       以上代码运行结果:

      2017-05-10 14:41:57 【北京市海淀区中关村南大街8号 香格里拉大酒店】 提供就餐服务 【奥迪A6】 提供出行服务

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326688127&siteId=291194637