V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
zhangqian99
V2EX  ›  Java

在 bean 之间复制具有不同名称的属性,不使用其他依赖库的情况下

  •  
  •   zhangqian99 · Nov 14, 2023 · 4273 views
    This topic created in 895 days ago, the information mentioned may be changed or developed.

    例如:

    class ClassA{
        private String name;
        private Integer age;
        private List<C> cList;
        Private D d;
        省略 setter,getter
    } 
    
    class ClassB{
        private String differentName;
        private Integer differentAge;
        private List<C> differCList;
        private D differD;
        省略 setter,getter
    }
    
    22 replies    2023-11-14 14:33:34 +08:00
    chendy
        1
    chendy  
       Nov 14, 2023   ❤️ 3
    楼主这是提了个问题么?
    不依赖其他库,不考虑不同类型,最简单实现就是弄个 map 保存字段映射关系,然后处理
    然后伴随着业务的发展,不同类型需要处理,部分字段需要忽略,每次反射拿字段拿方法效率不行要缓存…最后就自己实现了一个 copy 库
    zero47
        2
    zero47  
       Nov 14, 2023
    让 A 给 B 做构造入参
    zhangqian99
        3
    zhangqian99  
    OP
       Nov 14, 2023
    @chendy 想写一个工具类,使用注解的方式,有没有好的思路
    aosan926
        4
    aosan926  
       Nov 14, 2023
    参考序列化与反序列化?
    jsboy
        5
    jsboy  
       Nov 14, 2023
    java 的话,直接 mapstruct 吧,别重复造轮子了。
    sumarker
        6
    sumarker  
    PRO
       Nov 14, 2023   ❤️ 1
    不管是怎样映射关系总是需要维护的:
    1.通过自定义注解,写在属性上,然后反射解析到对应的类属性上
    2.搞一个中间类处理
    3. 把映射关系,存在 xml 或者数据库里
    dc2002007
        7
    dc2002007  
       Nov 14, 2023
    搞 java 的总是喜欢把一些很简单的东西提出来讨论
    looo
        8
    looo  
       Nov 14, 2023
    写这代码,还不如老老实实去手动 get set 装个插件一件生成 set 方法。

    搞 copy 都是脱裤子放屁💨,有那时间早 set 好了。
    theniupa
        9
    theniupa  
       Nov 14, 2023
    有那时间早 set 好了+1
    SirYuxuan
        10
    SirYuxuan  
       Nov 14, 2023   ❤️ 1
    ```
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface PropertyMapping {
    String value();
    }

    ```
    ```
    import java.lang.reflect.Field;

    public class BeanMapper {

    public static void copyProperties(Object source, Object destination) {
    Class<?> sourceClass = source.getClass();
    Class<?> destClass = destination.getClass();

    Field[] sourceFields = sourceClass.getDeclaredFields();

    for (Field sourceField : sourceFields) {
    if (sourceField.isAnnotationPresent(PropertyMapping.class)) {
    String sourceFieldName = sourceField.getName();
    String destinationFieldName = sourceField.getAnnotation(PropertyMapping.class).value();

    try {
    Field destField = destClass.getDeclaredField(destinationFieldName);
    sourceField.setAccessible(true);
    destField.setAccessible(true);

    Object value = sourceField.get(source);
    destField.set(destination, value);
    } catch (NoSuchFieldException | IllegalAccessException e) {
    e.printStackTrace(); // 处理异常,可以根据实际情况进行调整
    }
    }
    }
    }
    }

    ```
    Plutooo
        11
    Plutooo  
       Nov 14, 2023
    重复造的轮子对比 mapstruct 有什么优势呢
    SirYuxuan
        12
    SirYuxuan  
       Nov 14, 2023
    不太明白为啥一点技术的氛围都没有呢,都会说在造轮子,up 说不定只是想学习一下实现的思路呢,技术无罪
    zhangqian99
        13
    zhangqian99  
    OP
       Nov 14, 2023
    @Plutooo 这个是外包项目,在甲方虚拟机离线环境下编程,没有办法
    yazinnnn0
        14
    yazinnnn0  
       Nov 14, 2023
    https://github.com/mapstruct/mapstruct

    从最早的 commit 看, 抄过来用用
    yazinnnn0
        15
    yazinnnn0  
       Nov 14, 2023
    另外, 离线开发都没有给 mvn 仓库镜像吗? 难道要手搓 framework?
    Navee
        16
    Navee  
       Nov 14, 2023   ❤️ 1
    '''java
    class ClassA{
    private String name;
    private Integer age;
    private List<C> cList;
    Private D d;

    public ClassA(ClassB classB){
    ClassA a = new ClassA();
    //映射逻辑
    return a;
    }
    省略 setter,getter
    }

    class ClassB{
    private String differentName;
    private Integer differentAge;
    private List<C> differCList;
    private D differD;

    public ClassB(ClassA classA){
    ClassB b = new ClassB();
    //映射逻辑
    return b;
    }

    省略 setter,getter
    }
    '''
    chendy
        17
    chendy  
       Nov 14, 2023
    @zhangqian99 #3 那你好像已经把答案说出来了…
    注解的方式不一定最优,因为需要处理的逻辑量更大,如果要转换的东西本来就不多,那直接反射更方便
    其实还有一些办法比如生成 get set 代码之类的,差别其实不大
    另外如果是甲方离线环境…如果有入口的话直接把 mapstruct 或者其他库的 jar 包传进去配到依赖里也行
    lyxeno
        18
    lyxeno  
       Nov 14, 2023
    get set 好了,方便 IDE 重构和分析。
    gabon
        19
    gabon  
       Nov 14, 2023 via iPhone
    不要用反射,离线环境考虑把 mapstruct 的 jar 包打到 classpath 里
    xuanbg
        20
    xuanbg  
       Nov 14, 2023
    通用的话就是加注解,然后自己写个静态方法调用就成。
    jorneyr
        21
    jorneyr  
       Nov 14, 2023
    自己实现一个工具,不就是不依赖其他库了么。
    allecnm
        22
    allecnm  
       Nov 14, 2023
    get set 就行了呗
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2650 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 85ms · UTC 15:55 · PVG 23:55 · LAX 08:55 · JFK 11:55
    ♥ Do have faith in what you're doing.