Java Introspection instance analysis

  • 2020-12-10 00:42:54
  • OfStack

The number of contours in the image, where vector's size represents the number of points on the contour. Understand JavaBean

The English word for introspection is IntroSpector, which is mainly used to operate on JavaBean. JavaBean is a special Java class, in which some methods conform to a certain naming rule. If some methods in 1 Java class conform to a certain naming rule, it can be used as JavaBean.

JavaBean is a special KIND of Java class, which is mainly used to pass data information. The methods in this java class are mainly used to access private fields, and the method names conform to some naming rules.

If you want to pass more than one piece of information between two modules, you can encapsulate this information in a single JavaBean, an instance object of JavaBean commonly known as a value object (ValueObject, short for VO). This information is stored in private fields in the class. If the values of these fields are read or set, they need to be accessed through 1 corresponding method. What do you think of the names of these methods? The attributes of JavaBean are determined by the setter and getter methods, not by the member variables. If the method name is setId, that means setting id, and to which variable do you save it, with a tube? If the method name is getId, the Chinese meaning is to get id, as to which variable you take it from, with a tube? Remove the set prefix, and the rest is the property name, and if the second letter of the rest is lowercase, change the first letter of the rest to small.

Such as:

The attribute name of setId() -- > id

The attribute name of isLast() -- > last

What is the attribute name of setCPU? -- > CPU

What is the attribute name of getUPS? -- > UPS

In summary, when a class is used as javaBean, JavaBean attributes are inferred from the method name, and it does not see the member variables inside the java class at all.

A class that fits the characteristics of JavaBean can be used as normal class 1, but using it as JavaBean certainly requires a few additional benefits before we can understand and apply JavaBean! The benefits are as follows:

In JavaEE development, JavaBean is often used. Many environments require JavaBean to operate in the same way that others do, and you don't have much of a choice!

API, which operates on JavaBean, is provided in JDK. This set of API is called introspection. If you have to go to getX to access private x, how to do it, 1 difficulty? It is more convenient to operate JavaBean with the introspection set api than with regular classes.

Simple introspection for JavaBean

java.beans.PropertyDescriptor class is mainly used to get an JavaBean attribute in an Class object attribute set, and then call getReadMethod(), getWriteMethod() methods to get the corresponding get, set methods.

Code examples:

Domain class:

[cpp]viewplaincopy

intmain()


package ustc.lichunchun.bean;
import java.util.Date;
public class ReflectPoint { 
  private Date birthday = new Date();
private int x;
public int y;
public String str1 = "ball";
public String str2 = "basketball";
public String str3 = "itcast";
public ReflectPoint(int x, int y) {
	super();
	this.x = x;
	this.y = y;
}
@Override 
  public int hashCode() {
	final int prime = 31;
	int result = 1;
	result = prime * result + x;
	result = prime * result + y;
	return result;
}
@Override 
  public Boolean equals(Object obj) {
	if (this == obj) 
	      return true;
	if (obj == null) 
	      return false;
	if (getClass() != obj.getClass()) 
	      return false;
	final ReflectPoint other = (ReflectPoint) obj;
	if (x != other.x) 
	      return false;
	if (y != other.y) 
	      return false;
	return true;
}
@Override 
  public String toString(){
	return str1 + ":" + str2 + ":" + str3;
}
public int getX() {
	return x;
}
public void setX(int x) {
	this.x = x;
}
public int getY() {
	return y;
}
public void setY(int y) {
	this.y = y;
}
public Date getBirthday() {
	return birthday;
}
public void setBirthday(Date birthday) {
	this.birthday = birthday;
}
}

Simple introspection operation:


package ustc.lichunchun.bean;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class IntroSpectorTest {
	public static void main(String[] args) throws Exception {
		ReflectPoint pt1 = new ReflectPoint(3, 5);
		String propertyName = "x";
		//"x"-->"X"-->"getX"-->MethodGetX--> 
		getProperty(pt1, propertyName);
		Object value = 7;
		setProperty(pt1, propertyName, value);
		System.out.println(pt1.getX());
	}
	private static void setProperty(Object pt1, String propertyName, Object value) 
	      throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
		Method methodSetX = pd.getWriteMethod();
		methodSetX.invoke(pt1, value);
	}
	private static Object getProperty(Object pt1, String propertyName) 
	      throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
		Method methodGetX = pd.getReadMethod();
		methodGetX.invoke(pt1);
	}
}

Complex introspection operation on JavaBean

Find and set the x attribute of an RefectPoint object by traversing all the attributes of BeanInfo. To view a class as JavaBean in a program is to call the IntroSpector.getBeanInfo method, and the resulting BeanInfo object encapsulates the result information of viewing the class as JavaBean.

Complex introspection operation:


package ustc.lichunchun.bean;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class IntroSpectorTest {
	public static void main(String[] args) throws Exception {
		ReflectPoint pt1 = new ReflectPoint(3, 5);
		String propertyName = "x";
		//"x"-->"X"-->"getX"-->MethodGetX--> 
		Object retVal = getProperty(pt1, propertyName);
		System.out.println(retVal);
		Object value = 7;
		setProperty(pt1, propertyName, value);
		System.out.println(pt1.getX());
	}
	private static void setProperty(Object pt1, String propertyName, Object value) 
	      throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
		Method methodSetX = pd.getWriteMethod();
		methodSetX.invoke(pt1, value);
	}
	private static Object getProperty(Object pt1, String propertyName) 
	      throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		/* 
    PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass()); 
    Method methodGetX = pd.getReadMethod(); 
    methodGetX.invoke(pt1); 
    */
		BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
		PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
		Object retVal = null;
		for (PropertyDescriptor pd : pds){
			if(pd.getName().equals(propertyName)){
				Method methodGetX = pd.getReadMethod();
				retVal = methodGetX.invoke(pt1);
				break;
			}
		}
		return retVal;
	}
}

Operate JavaBean using the BeanUtils toolkit

Based on the previous introspection example, the BeanUtils class is used to set the property of get before setting its set as a new value. The get property returns a string, and the set property can accept any type of object, usually a string.

Use the PropertyUtils class to set the property of get before setting its set to a new value. The get property returns the property's original type, and set accepts only the property's original type.

Note: Before using these two classes, you need to import the jar packages commons-ES146en. jar and ES148en-ES149en-1.1.jar in the lib folder of the eclipse project, and AddtoBuildPath.

Code examples:


package ustc.lichunchun.bean;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
public class IntroSpectorTest {
	public static void main(String[] args) throws Exception {
		ReflectPoint pt1 = new ReflectPoint(3, 5);
		String propertyName = "x";
		//"x"-->"X"-->"getX"-->MethodGetX--> 
		Object retVal = getProperty(pt1, propertyName);
		System.out.println(retVal);
		Object value = 7;
		setProperty(pt1, propertyName, value);
		System.out.println(BeanUtils.getProperty(pt1, "x").getClass().getName());
		//String 
		BeanUtils.setProperty(pt1, "x", "9");
		System.out.println(pt1.getX());
		/* 
    Map map = {name:"zxx",age:18};//java7 The new features  
    BeanUtils.setProperty(map, "name", "lcc"); 
    */
		BeanUtils.setProperty(pt1, "birthday.time", "111");
		// Support attribute chains  
		System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));
		PropertyUtils.setProperty(pt1, "x", 23);
		System.out.println(PropertyUtils.getProperty(pt1, "x").getClass().getName());
		//Integer 
		/* 
    BeanUtils and PropertyUtils The difference between:  
    BeanUtils Pair as a string JavaBean Operate, and you can operate Map Class, and can be said JavaBean and Map Convert from one to another (describe , populate) 
    PropertyUtils In order to JavaBean The data type of the property itself operates on    
     */
	}
	private static void setProperty(Object pt1, String propertyName, Object value) 
	      throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass());
		Method methodSetX = pd.getWriteMethod();
		methodSetX.invoke(pt1, value);
	}
	private static Object getProperty(Object pt1, String propertyName) 
	      throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		/* 
    PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass()); 
    Method methodGetX = pd.getReadMethod(); 
    methodGetX.invoke(pt1); 
    */
		BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
		PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
		Object retVal = null;
		for (PropertyDescriptor pd : pds){
			if(pd.getName().equals(propertyName)){
				Method methodGetX = pd.getReadMethod();
				retVal = methodGetX.invoke(pt1);
				break;
			}
		}
		return retVal;
	}
}

conclusion

That is the end of this article on introspective instance analysis of Java, and I hope it will be helpful to you. Interested friends can continue to refer to other related topics in this site, if there is any deficiency, welcome to comment out. Thank you for your support!


Related articles: