Introspector
Java JDK Introspector
在开发框架的时候经常会用到Java类的
get/set
方法设置或者获取值,但是每次都是用反射来完成此类操作或与麻烦,JDK提供了 一套API,专门操作Java对象的属性。内省专门操作Java对象的属性。
在Java中private int id
这种叫做字段field
,而get/set
方法才被叫做属性property
。
Java中的属性是指设置和读取字段的方法。
属性名称就是去掉get/set
后面的部分
package cn.pickle.entity;
import lombok.Data;
/**
* @author Pickle
* @version V1.0
* @date13:53 2022/12/14
*/
@Data //该注解自动生成 get/set 方法
public class Student {
private Long id; //field 字段
private String password; //field 字段
private Integer classNumber;//field 字段
public String getTest(){
return "TEST";
}
测试函数
package cn.pickle.introspector;
import cn.pickle.entity.Student;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
/**
* @author Pickle
* @version V1.0
* @date 2022/12/16 14:11
*/
public class demo {
public static void main(String[] args) throws IntrospectionException {
//获得Student属性封装到beanInfo中
final BeanInfo beanInfo = Introspector.getBeanInfo(Student.class);
//得到类中的所有属性描述器
final PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
System.out.println("属性的个数为" + propertyDescriptors.length);
for (PropertyDescriptor pd :
propertyDescriptors) {
System.out.println("属性" + pd.getName());
}
}
}
结果
从
属性test
可以看出获得的属性和字段并没有关系,而属性class
则是父类的getClass()
方法
PropertyDescriptor
propertyDescriptor通过反射快速操作JavaBean的
getter/setter
方法。
PropertyDescriptor获取get/set
方法的API
实例
package cn.pickle.introspector;
import cn.pickle.entity.Student;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
/**
* @author Pickle
* @version V1.0
* @date 2022/12/16 14:11
*/
public class demo {
public static void main(String[] args) {
try {
//获取描述Student的Class实例
final Class<?> stuClass = Class.forName("cn.pickle.entity.Student");
final Student student = (Student)stuClass.newInstance();
//获取id的属性描述器
final PropertyDescriptor pd = new PropertyDescriptor("id", Student.class);
//setId()
final Method writeId = pd.getWriteMethod();
//getId()
final Method readId = pd.getReadMethod();
System.out.println(student.toString());
writeId.invoke(student,1L);
System.out.println(student.toString());
System.out.println("利用属性描述器获取的get方法读取id的值为:" + readId.invoke(student,null));
}catch (Exception error){
System.out.println("没有找到该类" + error.getMessage());
}
}
}
输出
Apache BeanUtils
更高效的内省框架
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
简单使用
package cn.pickle.introspector;
import cn.pickle.entity.Student;
import org.apache.commons.beanutils.BeanUtils;
import java.beans.*;
import java.lang.reflect.InvocationTargetException;
/**
* @author Pickle
* @version V1.0
* @date 2022/12/16 14:11
*/
public class demo {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
Student student = new Student();
final String id = BeanUtils.getProperty(student, "id");
System.out.println("BeanUtils 获取的 id 为: " + id);
BeanUtils.setProperty(student,"id",1L);
System.out.println("BeanUtils 设置后的Student" + student.toString());
}
}
输出
ConvertUtils
实现非基本类型的自定义转换封装
将Map属性批量封装到Bean中
package cn.pickle.introspector;
import cn.pickle.entity.Student;
import org.apache.commons.beanutils.BeanUtils;
import java.beans.*;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
/**
* @author Pickle
* @version V1.0
* @date 2022/12/16 14:11
*/
public class demo {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
Student student = new Student();
Map<String,String> map = new HashMap<>();
map.put("id","1");
map.put("classNumber","1");
map.put("password","1");
BeanUtils.populate(student,map);
System.out.println(student);
}
}
输出
但是如果里面包含不是基本类型,我们在原来的基础上给Student加上一个Date字段
package cn.pickle.introspector;
import cn.pickle.entity.Student;
import org.apache.commons.beanutils.BeanUtils;
import java.beans.*;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
/**
* @author Pickle
* @version V1.0
* @date 2022/12/16 14:11
*/
public class demo {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
Student student = new Student();
Map<String,String> map = new HashMap<>();
map.put("id","1");
map.put("classNumber","1");
map.put("password","1");
map.put("birthday","2001-01-01");
BeanUtils.populate(student,map);
System.out.println(student);
}
}
直接报错
意思就是DateConverter不支持默认的String到Date转换,有两种解决方案。
- 自定义转换器然后用ConvertUtils注册。
package cn.pickle.introspector;
import cn.pickle.entity.Student;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import java.lang.reflect.InvocationTargetException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author Pickle
* @version V1.0
* @date 2022/12/16 14:11
*/
@SuppressWarnings("unchecked")
public class demo {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
Student student = new Student();
Map<String,String> map = new HashMap<>();
map.put("id","1");
map.put("classNumber","1");
map.put("password","1");
map.put("birthday","2001-01-01");
ConvertUtils.register(new Converter() {
/**
* @param <T>
* @param aClass 目标类型
* @param o 当前传入的值
* @return
*/
@Override
public <T> T convert(Class<T> aClass, Object o) {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
if(o instanceof String){// String -> Date
String date = (String) o;
try {
final Date parse = df.parse(date);
return (T) parse;
} catch (ParseException e) {
e.printStackTrace();
}
}else{//Date -> String
final String format = df.format((Date) o);
return (T) format;
}
return null;
}
}, Date.class);
BeanUtils.populate(student,map);
System.out.println(student);
}
}
结果
- 使用提供的转换器
package cn.pickle.introspector;
import cn.pickle.entity.Student;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import java.lang.reflect.InvocationTargetException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author Pickle
* @version V1.0
* @date 2022/12/16 14:11
*/
@SuppressWarnings("unchecked")
public class demo {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
Student student = new Student();
Map<String,String> map = new HashMap<>();
map.put("id","1");
map.put("classNumber","1");
map.put("password","1");
map.put("birthday","2001-01-01");
// ConvertUtils.register(new Converter() {
// /**
// * @param <T>
// * @param aClass 目标类型
// * @param o 当前传入的值
// * @return
// */
// @Override
// public <T> T convert(Class<T> aClass, Object o) {
// DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
// if(o instanceof String){// String -> Date
// String date = (String) o;
// try {
// final Date parse = df.parse(date);
// return (T) parse;
// } catch (ParseException e) {
// e.printStackTrace();
// }
// }else{//Date -> String
// final String format = df.format((Date) o);
// return (T) format;
// }
// return null;
// }
// }, Date.class);
ConvertUtils.register(new DateLocaleConverter(),Date.class);
BeanUtils.populate(student,map);
System.out.println(student);
}
}
标签:map,java,String,student,内省,Student,import,Java
From: https://www.cnblogs.com/poteitoutou/p/16987571.html