spring-core依赖中,带有反射工具类ReflectionUtils,导包如下:
import org.springframework.util.ReflectionUtils;
2 Field相关使用
(1)ReflectionUtils.makeAccessible、ReflectionUtils.findField使用:
实际上,ReflectionUtils.makeAccessible本质就是调用field.setAccessible(true),让非public修饰的字段,可以操作如protected、private修饰的字段。如下,ReflectionUtils.findField不使用ReflectionUtils.makeAccessible也是可以的,但是ReflectionUtils.getField是需要使用的。
新建注解类MyFruit:
package com.xiaoxu.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyFruit {
String fruitName();
int number();
新建一个DTO类:FruitDTO:
package com.xiaoxu.dto;
import com.xiaoxu.annotation.MyFruit;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
* @author xiaoxu
* @date 2022-02-14
* Ymybatis:com.xiaoxu.dto.FruitDto
public class FruitDto {
@MyFruit(fruitName = "荔枝",number = 1)
private String one;
@MyFruit(fruitName = "菠萝",number = 2)
private String two;
public static void main(String[] args) {
Class<FruitDto> clazz = FruitDto.class;
Field[] f = clazz.getDeclaredFields();
System.out.println(Arrays.toString(f));
Map<Integer,Field> m = new HashMap<>();
for (Field field : f) {
System.out.println("*********开始*********");
System.out.printf("我是field:%s%n",field);
String fieldName = field.getName();
System.out.printf("我是字段名:%s%n",fieldName);
Field field1 = ReflectionUtils.findField(clazz, fieldName);
if(field1 !=null){
ReflectionUtils.makeAccessible(field1);
System.out.printf("ReflectionUtils的findField方法获取字段:%s%n",field1);
if(field.isAnnotationPresent(MyFruit.class)){
MyFruit myFruit = field.getAnnotation(MyFruit.class);
System.out.printf("字段field调用getAnnotation获取注解:%s%n",myFruit);
System.out.printf("map.put返回值为null,说明key不重复:%s%n",m.put(myFruit.number(),field));
System.out.printf("map.put返回值为value(这里是Filed的name),说明key重复了:%s%n",m.put(myFruit.number(),field).getName());
System.out.printf("获取注解的fruitName:%s%n",myFruit.fruitName());
System.out.printf("获取注解的number:%s%n",myFruit.number());
System.out.println("*********结束*********");
System.out.printf("字典如下:%s%n",m);
for(Map.Entry<Integer,Field> e:m.entrySet()){
System.out.printf("字典的key:%s,value:%s%n",e.getKey(),e.getValue());
System.out.println(e.getValue().getAnnotation(MyFruit.class).fruitName());
System.out.println(e.getValue().getAnnotation(MyFruit.class).number());
执行结果如下:
[private java.lang.String com.xiaoxu.dto.FruitDto.one, private java.lang.String com.xiaoxu.dto.FruitDto.two]
*********开始*********
我是field:private java.lang.String com.xiaoxu.dto.FruitDto.one
我是字段名:one
ReflectionUtils的findField方法获取字段:private java.lang.String com.xiaoxu.dto.FruitDto.one
字段field调用getAnnotation获取注解:@com.xiaoxu.annotation.MyFruit(fruitName=荔枝, number=1)
map.put返回值为null,说明key不重复:null
map.put返回值为value(这里是Filed的name),说明key重复了:one
获取注解的fruitName:荔枝
获取注解的number:1
*********结束*********
*********开始*********
我是field:private java.lang.String com.xiaoxu.dto.FruitDto.two
我是字段名:two
ReflectionUtils的findField方法获取字段:private java.lang.String com.xiaoxu.dto.FruitDto.two
字段field调用getAnnotation获取注解:@com.xiaoxu.annotation.MyFruit(fruitName=菠萝, number=2)
map.put返回值为null,说明key不重复:null
map.put返回值为value(这里是Filed的name),说明key重复了:two
获取注解的fruitName:菠萝
获取注解的number:2
*********结束*********
字典如下:{1=private java.lang.String com.xiaoxu.dto.FruitDto.one, 2=private java.lang.String com.xiaoxu.dto.FruitDto.two}
字典的key:1,value:private java.lang.String com.xiaoxu.dto.FruitDto.one
字典的key:2,value:private java.lang.String com.xiaoxu.dto.FruitDto.two
(2)ReflectionUtils.doWithFields使用:
注解MFruit:
package com.xiaoxu.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MFruit {
String name();
long num();
dto下新建PreciousFruit类:
package com.xiaoxu.dto;
import com.xiaoxu.annotations.MFruit;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
* @author xiaoxu
* @date 2022-02-14 22:26
* mybatis_learn:com.xiaoxu.dto.PreciousFruit
public class PreciousFruit {
@MFruit(name = "芒果",num = 1)
private String fruitOne;
@MFruit(name = "猕猴桃",num = 2)
private String fruitTwo;
@MFruit(name = "香蕉",num = 3)
public String fruitThree;
@MFruit(name = "砂糖橘",num = 4)
protected String fruitFour;
public static Map<Long,Field> injectMethod(){
Map<Long,Field> m = new HashMap<>();
ReflectionUtils.doWithFields(PreciousFruit.class,
new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
System.out.println("我是回调,哈哈哈哈");
if(field.isAnnotationPresent(MFruit.class)){
System.out.printf("字段:%s;具有注解MFruit%n",field);
long number = field.getAnnotation(MFruit.class).num();
if(m.put(number,field)!=null){
System.out.println("该水果number重复,跳过");
System.out.println("********");
});
return m;
public static void main(String[] args) {
Map<Long, Field> longFieldMap = PreciousFruit.injectMethod();
longFieldMap.forEach((k,v)->System.out.printf("map的key:%s,value:%s%n",k,v));
执行结果:
我是回调,哈哈哈哈
字段:private java.lang.String com.xiaoxu.dto.PreciousFruit.fruitOne;具有注解MFruit
********
我是回调,哈哈哈哈
字段:private java.lang.String com.xiaoxu.dto.PreciousFruit.fruitTwo;具有注解MFruit
********
我是回调,哈哈哈哈
字段:public java.lang.String com.xiaoxu.dto.PreciousFruit.fruitThree;具有注解MFruit
********
我是回调,哈哈哈哈
字段:protected java.lang.String com.xiaoxu.dto.PreciousFruit.fruitFour;具有注解MFruit
********
map的key:1,value:private java.lang.String com.xiaoxu.dto.PreciousFruit.fruitOne
map的key:2,value:private java.lang.String com.xiaoxu.dto.PreciousFruit.fruitTwo
map的key:3,value:public java.lang.String com.xiaoxu.dto.PreciousFruit.fruitThree
map的key:4,value:protected java.lang.String com.xiaoxu.dto.PreciousFruit.fruitFour
Process finished with exit code 0
(3)ReflectionUtils.getField使用:
ReflectionUtils.getField本质是调用的field.get(target),getField获取对象该字段的值时,引用类型若未使用setter赋值,那么默认值就是null。另外,ReflectionUtils.getField使用时,若是protected或者private修饰的字段,需先使用ReflectionUtils.makeAccessible(field)。
package com.xiaoxu.dto;
import com.xiaoxu.annotation.MyFruit;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
* @author xiaoxu
* @date 2022-02-15 21:31
* mybatis_learn:com.xiaoxu.dto.FruitDto
public class FruitDto {
@MyFruit(fruitName = "荔枝",number = 1)
public String one;
@MyFruit(fruitName = "菠萝",number = 2)
private String two;
@MyFruit(fruitName = "车厘子",number = 3)
protected String three;
public void setOne(String one) {
this.one = one;
public void setTwo(String two) {
this.two = two;
public void setThree(String three) {
this.three = three;
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Class<FruitDto> clazz = FruitDto.class;
FruitDto cls = clazz.newInstance();
Field[] fields = clazz.getDeclaredFields();
cls.setThree("nihao");
for (Field field : fields) {
System.out.printf("我是字段%s%n",field);
System.out.printf("我是字段的修饰符:%s%n",field.getModifiers());
switch(field.getModifiers()){
case 1:
System.out.println("我是public");
Object filed1 = ReflectionUtils.getField(field,cls);
System.out.printf("我是field:%s%n",filed1);
break;
case 2:
System.out.println("我是private");
ReflectionUtils.makeAccessible(field);
Object filed2 = ReflectionUtils.getField(field,cls);
System.out.printf("我是field:%s%n",filed2);
break;
case 4:
System.out.println("我是protected");
ReflectionUtils.makeAccessible(field);
Object filed3 = ReflectionUtils.getField(field,cls);
System.out.printf("我是field:%s%n",filed3);
break;
default:
System.out.println("暂时只支持public、protected、private.");
if(Modifier.isProtected(field.getModifiers())){
System.out.println("我是保护的");
ReflectionUtils.makeAccessible(field);
Object field1 = ReflectionUtils.getField(field, cls);
System.out.println(field1);
System.out.println("****************");
执行结果:
我是字段public java.lang.String com.xiaoxu.dto.FruitDto.one
我是字段的修饰符:1
我是public
我是field:null
****************
我是字段private java.lang.String com.xiaoxu.dto.FruitDto.two
我是字段的修饰符:2
我是private
我是field:null
****************
我是字段protected java.lang.String com.xiaoxu.dto.FruitDto.three
我是字段的修饰符:4
我是protected
我是field:nihao
我是保护的
nihao
****************
(4)ReflectionUtils.setField使用:
实体类中重写toString便于观察,无需加入setter方法。且使用ReflectionUtils.setField前,也需要为private、protected修饰的字段执行setAccessible(ture)操作。
package com.xiaoxu.dto;
import com.xiaoxu.annotations.MyFruit;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Modifier;
import java.util.Arrays;
* @author xiaoxu
* @date 2022-02-16 22:31
* mybatis_learn:com.xiaoxu.dto.FruitDto2
public class FruitDto2 {
@MyFruit(fruitName = "牛油果",number = 1)
public String one;
@MyFruit(fruitName = "葡萄",number = 2)
private String two;
@MyFruit(fruitName = "桃子",number = 3)
protected String three;
@Override
public String toString() {
return "水果2{" +
"one='" + one + '\'' +
", two='" + two + '\'' +
", three='" + three + '\'' +
'}';
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Class<? extends FruitDto2> clazz = FruitDto2.class;
FruitDto2 f = clazz.newInstance();
Arrays.stream(clazz.getDeclaredFields()).forEach(field->{
System.out.println(field);
if(Modifier.isPrivate(field.getModifiers())||Modifier.isProtected(field.getModifiers())){
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field,f,"one");
});
System.out.println(f);
结果如下:
public java.lang.String com.xiaoxu.dto.FruitDto2.one
private java.lang.String com.xiaoxu.dto.FruitDto2.two
protected java.lang.String com.xiaoxu.dto.FruitDto2.three
水果2{one='one', two='one', three='one'}
spring:ReflectionUtils工具包使用1 前言spring-core依赖中,带有反射工具类ReflectionUtils,导包如下:import org.springframework.util.ReflectionUtils;2 使用(1)ReflectionUtils.makeAccessible、ReflectionUtils.findField使用:新建注解类MyFruit:package com.xiaoxu.annotation;import java.
在项目中部分方法采用反射,通过类访问类的属性,通过类反问方法,通过属性访问方法。以及常用异常的处理在等可以使用反射出处理。
public abstract class ReflectionUtils {
//根据类和属性名称查找属性字段
//Attempt to find a {@link Field field} on the supplied {@link Class} w
AVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
通俗点讲,反射就是把java类中的各种成分映射成一个个的Java对象。
例如:类的class声明(class对象),变量(field),方法(method)等等信息,利用反射技术可以对一个类进行解剖,动态获取信息进行处理。1、获取Class对象的三种方式
1.1 Object ——> getClass(
System.out.println("---------- findMethod ----------");
// 获取方法
Method method1 = ReflectionUtils.findMethod(DemoObject.class, "method01");
Method method2 = ReflectionUtils.findMethod(DemoObject.class, "method02");
System.out.println(method1);
System.out.p.
工程在本地windows机器上面安装weblogic部署正常,迁移到linux(64位)下安装32位的weblogic10.3出现异常
<Unable to set the activation state to true for the application 'ETeller'.
weblogic.application.ModuleException:
findField(Class<?> clazz, String name, Class<?> type)
根据字段名称查找Field
Field findField(Class<?> clazz, String name)
给指定字段设置值
setField(Field field, Object target, Object value)
获取指定字段的值
getField(Field field, Objec
AnnotationUtils是Spring框架提供的一个工具类,用于获取指定类、方法、字段等上指定的注解信息。使用AnnotationUtils可以简化代码编写,并且可以避免出现重复的注解代码。
下面是AnnotationUtils的使用示例:
1. 获取指定类上的注解信息:
@MyAnnotation(value = "class")
public class MyClass {
// ...
Class<?> clazz = MyClass.class;
MyAnnotation annotation = AnnotationUtils.getAnnotation(clazz, MyAnnotation.class);
System.out.println(annotation.value()); // 输出 "class"
2. 获取指定方法上的注解信息:
public class MyClass {
@MyAnnotation(value = "method")
public void myMethod() {
// ...
Method method = MyClass.class.getMethod("myMethod");
MyAnnotation annotation = AnnotationUtils.getAnnotation(method, MyAnnotation.class);
System.out.println(annotation.value()); // 输出 "method"
3. 获取指定字段上的注解信息:
public class MyClass {
@MyAnnotation(value = "field")
private String myField;
// ...
Field field = MyClass.class.getDeclaredField("myField");
MyAnnotation annotation = AnnotationUtils.getAnnotation(field, MyAnnotation.class);
System.out.println(annotation.value()); // 输出 "field"
注意事项:
- 如果指定的类、方法、字段上没有指定的注解,则AnnotationUtils.getAnnotation()方法会返回null。
- 如果需要获取指定类上的注解信息,也可以使用Spring提供的@AnnotatedElementUtils工具类,该工具类可以获取类、方法、字段等上所有的注解信息。