java中使用反射将javaBean转为map

本文介绍了一种将JavaBean对象转换为Map集合的方法,通过反射机制获取对象的所有字段,并将其值存入Map中。同时,引入了FieldName注解来指定字段在Map中的键名,提供了忽略某些字段的功能。

查阅资料遇到一个javaBean转为map的方法,在此记录一下:

public static Map<String, Object> javaBean2Map(Object bean) throws IllegalAccessException {
        Map<String, Object> result = new HashMap<>();

        Class<?> sourceClass = bean.getClass();
        //拿到所有的字段,不包括继承的字段
        Field[] sourceFiled = sourceClass.getDeclaredFields();
        for (Field field : sourceFiled) {
            field.setAccessible(true);
            //设置可访问,不然拿不到private
            FieldName fieldName = field.getAnnotation(FieldName.class);
            if (fieldName == null) {
                result.put(field.getName(), field.get(bean));
            } else {
                if (fieldName.Ignore()) continue;
                result.put(fieldName.value(), field.get(bean));
            }
        }
        return result;
    }

 

代码中的FieldName是新建的类:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
public @interface FieldName {
  String value() default "";
   boolean Ignore() default false;
}

 

测试用例:

public static void main(String[] args) throws IllegalAccessException {
        Employee employee = new Employee();
        employee.setBirthDay(new Date());
        employee.setEmplId("1000");
        employee.setEmplName("信息技术部");
        employee.setEmplName("张三");

        Map<String,Object> map=  javaBean2Map(employee);
        Set<String> keySet = map.keySet();
     System.out.println("employee转为map后的输出结果:");
     for (String key:keySet
    ) {
     System.out.println("key:"+key+" value:"+map.get(key));

    }
 }

测试结果:

转载于:https://www.cnblogs.com/obonika/p/10221253.html

Java 中,将对象转换为 `Map` 可以通过多种方式实现,常见的方法包括使用 **反射**、**Apache Commons BeanUtils**、**Jackson** 或 **Spring BeanWrapper**。以下是详细方案和代码示例: --- ### **方法 1:使用反射(手动实现)** 通过反射获取对象的所有字段及其值,存入 `Map`: ```java import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; public class ObjectToMap { public static Map<String, Object> convert(Object obj) throws IllegalAccessException { Map<String, Object> map = new HashMap<>(); Class<?> clazz = obj.getClass(); for (Field field : clazz.getDeclaredFields()) { field.setAccessible(true); // 允许访问私有字段 String name = field.getName(); Object value = field.get(obj); map.put(name, value); } return map; } public static void main(String[] args) throws IllegalAccessException { Person person = new Person("Alice", 25); Map<String, Object> map = convert(person); System.out.println(map); // 输出: {name=Alice, age=25} } } class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } } ``` **注意**:反射会访问所有字段(包括私有字段),但性能较差,且可能因安全策略受限。 --- ### **方法 2:使用 Apache Commons BeanUtils** 通过 `BeanUtils.describe()` 将 JavaBean 转换为 `Map`(需处理 `IllegalAccessException` 和 `InvocationTargetException`): ```java import org.apache.commons.beanutils.BeanUtils; import java.util.Map; public class BeanToMap { public static void main(String[] args) throws Exception { Person person = new Person("Bob", 30); Map<String, String> map = BeanUtils.describe(person); // 值均为 String 类型 System.out.println(map); // 输出: {name=Bob, age=30, class=class Person} } } ``` **缺点**: - 生成的 `Map` 中值均为 `String` 类型(可能需额外转换)。 - 会包含 `class` 属性(需手动移除)。 --- ### **方法 3:使用 Jackson(推荐)** 通过 `ObjectMapper` 将对象序列化为 `Map`,支持复杂类型和嵌套对象: ```java import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Map; public class JacksonToMap { public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper(); Person person = new Person("Charlie", 35); // 对象转 Map Map<String, Object> map = mapper.convertValue(person, Map.class); System.out.println(map); // 输出: {name=Charlie, age=35} // Map 转回对象 Person newPerson = mapper.convertValue(map, Person.class); } } ``` **优点**: - 支持嵌套对象和集合类型。 - 类型安全,性能较好。 --- ### **方法 4:使用 Spring BeanWrapper** 通过 Spring 的 `BeanWrapper` 动态访问对象属性: ```java import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapperImpl; import java.util.HashMap; import java.util.Map; public class SpringToMap { public static Map<String, Object> convert(Object obj) { Map<String, Object> map = new HashMap<>(); BeanWrapper wrapper = new BeanWrapperImpl(obj); for (java.beans.PropertyDescriptor pd : wrapper.getPropertyDescriptors()) { String name = pd.getName(); if (!"class".equals(name)) { // 跳过 class 属性 Object value = wrapper.getPropertyValue(name); map.put(name, value); } } return map; } public static void main(String[] args) { Person person = new Person("David", 40); Map<String, Object> map = convert(person); System.out.println(map); // 输出: {name=David, age=40} } } ``` **适用场景**:Spring 项目中优先使用。 --- ### **方法 5:手动实现(Getter 方法)** 如果对象结构简单,可直接通过 Getter 方法填充 `Map`: ```java import java.util.HashMap; import java.util.Map; public class ManualToMap { public static Map<String, Object> convert(Person person) { Map<String, Object> map = new HashMap<>(); map.put("name", person.getName()); map.put("age", person.getAge()); return map; } public static void main(String[] args) { Person person = new Person("Eve", 28); Map<String, Object> map = convert(person); System.out.println(map); // 输出: {name=Eve, age=28} } } ``` **优点**:类型安全,性能最佳;**缺点**:需手动维护。 --- ### **关键问题与注意事项** 1. **性能**:反射 > BeanUtils > Jackson > 手动实现。推荐优先使用 **Jackson** 或手动实现。 2. **嵌套对象**:只有 Jackson 和 Spring BeanWrapper 能自动处理嵌套对象。 3. **字段过滤**:如需排除某些字段(如 `password`),需在转换后手动移除或使用注解(如 Jackson 的 `@JsonIgnore`)。 4. **安全性**:反射可能触发安全管理器限制,需确保权限。 --- ### **总结** | 方法 | 适用场景 | 是否支持嵌套对象 | 性能 | |--------------------|----------------------------|----------------|--------| | 反射 | 通用,无依赖 | 是 | 差 | | Apache BeanUtils | 简单 JavaBean | 否(值转为 String)| 中 | | Jackson | 复杂对象,Spring 项目 | 是 | 优 | | Spring BeanWrapper | Spring 环境 | 是 | 中 | | 手动 Getter | 固定结构对象 | 否 | 最佳 | **推荐方案**: - 非 Spring 项目:**Jackson**。 - Spring 项目:**Spring BeanWrapper** 或 **Jackson**。 - 简单对象:手动实现。 如果需要进一步优化(如忽略空值、自定义字段名),可以结合 Jackson 的注解: ```java import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @JsonInclude(JsonInclude.Include.NON_NULL) class Person { @JsonProperty("user_name") // 自定义 Map 中的键名 private String name; private int age; // getters/setters... } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值