记录:480
场景:java.lang.reflect.Field的使用,包括但不限于创建Field对象,使用Field对象获取实例字段值,使用Field对象设置实例字段值,使用Field对象获取实例字段上注解,以及其它常用方式使用。在Java反射机制中发挥重要作用。
版本:JDK 1.8,Spring Boot 2.6.3。
1.基础
1.1Field类
在JDK的java.lang.reflect.Field中对Field的官方说明如下:
A Field provides information about, and dynamic access to, a single field of a class or an interface. The reflected field may be a class (static) field or an instance field.
A Field permits widening conversions to occur during a get or set access operation, but throws an IllegalArgumentException if a narrowing conversion would occur.
1.2Java 反射机制
Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法。这种在运行时动态的获取信息以及动态调用对象的方法的功能称为Java 的反射机制。
2.创建Field对象
使用类的Class对象获取该类的Field对象。public修饰的字段使用getField和getFields获取Field对象。使用getDeclaredField和getDeclaredFields获取类所有声明的字段的Field对象。
//1.返回Field对象,是public关键字修饰成员字段
Class<?> clz01 = CityBO.class;
Field fd01 = clz01.getField("area");
Field[] fd02 = clz01.getFields();
StringBuilder sb01 = new StringBuilder();
Arrays.asList(fd02).forEach(item -> {
sb01.append(item.getName() + ",");
});
System.out.println("使用getField获取类的指定名称属性: " + fd01.getName());
System.out.println("使用getFields获取类的全部属性列表: " + sb01.toString());
//2.返回Field对象,声明的成员属性(包括private/protected/public)
Field fd03 = clz01.getDeclaredField("cityNo");
Field[] fd04 = clz01.getDeclaredFields();
System.out.println("使用getDeclaredField获取类的指定名称属性: " + fd03.getName());
StringBuilder sb02 = new StringBuilder();
Arrays.asList(fd04).forEach(item -> {
sb02.append(item.getName() + ",");
});
System.out.println("使用getDeclaredFields获取类的全部属性列表: " + sb02.toString());
3.使用Field对象获取实例字段值
使用Field对象获取实例字段值,包括如下方法:
public Object get(Object obj)
public boolean getBoolean(Object obj)
public byte getByte(Object obj)
public char getChar(Object obj)
public short getShort(Object obj)
public int getInt(Object obj)
public long getLong(Object obj)
public float getFloat(Object obj)
public double getDouble(Object obj)
其中,public Object get(Object obj)示例如下:
CityBO cityBO = new CityBO();
cityBO.setCityNo("350200");
cityBO.setCityName("厦门");
cityBO.setPopulation(530);
cityBO.area = 1700.61;
CityBO.position = "东南";
//1.获取private修饰变量值
Field fd0501 = CityBO.class.getDeclaredField("cityNo");
fd0501.setAccessible(true);
Object cityNoV = fd0501.get(cityBO);
//2.获取protected修饰变量值
Field fd0502 = CityBO.class.getDeclaredField("population");
fd0502.setAccessible(true);
Object populationV = fd0502.get(cityBO);
//3.获取public修饰变量值
Field fd0503 = CityBO.class.getDeclaredField("area");
Object areaV = fd0503.get(cityBO);
//4.获取public static修饰变量值
Field fd0504 = CityBO.class.getDeclaredField("position");
Object positionV = fd0504.get(cityBO);
//5.获取private static修饰变量值
Field fd0505 = CityBO.class.getDeclaredField("province");
fd0505.setAccessible(true);
Object provinceV = fd0505.get(cityBO);
System.out.println("cityBO值: " + cityBO.toString());
4.使用Field对象设置实例字段值
使用Field对象设置实例字段值,包括如下方法:
public void set(Object obj, Object value)
public void setBoolean(Object obj, boolean z)
public void setByte(Object obj, byte b)
public void setChar(Object obj, char c)
public void setShort(Object obj, short s)
public void setInt(Object obj, int i)
public void setLong(Object obj, long l)
public void setFloat(Object obj, float f)
public void setDouble(Object obj, double d)
其中,public void set(Object obj, Object value)示例如下:
CityBO cityBO01 = new CityBO();
cityBO01.setCityNo("350200");
cityBO01.setCityName("厦门");
cityBO01.setPopulation(530);
cityBO01.area = 1700.61;
cityBO01.position = "闽南";
System.out.println("cityBO01修改前: " + cityBO01.toString());
//1.设置private修饰变量值
Field fd060101 = CityBO.class.getDeclaredField("cityNo");
fd060101.setAccessible(true);
fd060101.set(cityBO01, "350100");
Field fd060102 = CityBO.class.getDeclaredField("cityName");
fd060102.setAccessible(true);
fd060102.set(cityBO01, "福州");
//2.获取protected修饰变量值
Field fd0602 = CityBO.class.getDeclaredField("population");
fd0602.setAccessible(true);
fd0602.set(cityBO01, 844);
//3.获取public修饰变量值
Field fd0603 = CityBO.class.getDeclaredField("area");
fd0603.set(cityBO01, 11968.53);
//4.获取public static修饰变量值
Field fd0604 = CityBO.class.getDeclaredField("position");
fd0604.set(cityBO01, "闽北");
//5.获取private static修饰变量值
Field fd0605 = CityBO.class.getDeclaredField("province");
fd0605.setAccessible(true);
fd0605.set(cityBO01, "福建省");
System.out.println("cityBO01修改后: " + cityBO01.toString());
5.使用Field对象获取实例字段上注解
使用Field对象获取实例字段上注解,在从注解中获取注解具体值,应用到需求场景中。
Field fd07 = CityVO.class.getDeclaredField("cityInfo");
Annotation ano01 = fd07.getAnnotation(CityFieldAno.class);
CityFieldAno cityFieldAno = (CityFieldAno) ano01;
System.out.println("获取注解值: code=" + cityFieldAno.code() + ",code=" + cityFieldAno.value());
Annotation[] ano02 = fd07.getAnnotations();
Annotation ano03 = fd07.getDeclaredAnnotation(CityFieldAno.class);
Annotation[] ano04 = fd07.getDeclaredAnnotations();
AnnotatedType ano05 = fd07.getAnnotatedType();
CityFieldAno[] ano06 = fd07.getAnnotationsByType(CityFieldAno.class);
CityFieldAno[] ano07 = fd07.getDeclaredAnnotationsByType(CityFieldAno.class);
6.其它常用方法
Field fd08 = CityBO.class.getField("area");
//1.返回Class对象,声明了Field属性的类
Class<?> clz02 = fd08.getDeclaringClass();
//2.返回属性名称
String name01 = fd08.getName();
//3.返回Modifier
int mod01 = fd08.getModifiers();
//4.返回true代表枚举类型,否则返回false
boolean bbl01 = fd08.isEnumConstant();
//5.返回true代表Synthetic类型,否则返回false
boolean bbl02 = fd08.isSynthetic();
//6.返回字段类型的Class对象
Class<?> clz03 = fd08.getType();
//7.返回字段类型的Type对象
Type type01 = fd08.getGenericType();
//8.返回字段的hashcode编码
int code = fd08.hashCode();
7.辅助类
7.1CityBO
在CityBO中包括public、private、protected、static等关键字修饰字段。
public class CityBO {
//private属性
private String cityNo;
private String cityName;
//protected属性
protected long population;
//public属性
public double area;
//public修饰的静态属性
public static String position;
//private修饰的静态属性
private static String province = "福建省";
public CityBO() {
}
public String getCityNo() {
return cityNo;
}
public void setCityNo(String cityNo) {
this.cityNo = cityNo;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public long getPopulation() {
return population;
}
public void setPopulation(long population) {
this.population = population;
}
@Override
public String toString() {
return "CityBO{" +
"cityNo='" + cityNo + '\'' +
", cityName='" + cityName + '\'' +
", population=" + population +
", area=" + area +
", position=" + position +
", province=" + province +
'}';
}
}
7.2CityFieldAno
作用在字段上的注解。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CityFieldAno {
//城市编码
String code();
//城市名称
String value() default "";
}
7.3CityVO
CityVO的字段上使用了注解。
public class CityVO {
@CityFieldAno(code = "350200",value = "厦门")
private String cityInfo;
public String getCityInfo() {
return cityInfo;
}
public void setCityInfo(String cityInfo) {
this.cityInfo = cityInfo;
}
}
以上,感谢。
2024年2月29日