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

2023-11-14 08:49:49 +08:00
 zhangqian99

例如:

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
}
2125 次点击
所在节点    Java
22 条回复
chendy
2023-11-14 08:55:16 +08:00
楼主这是提了个问题么?
不依赖其他库,不考虑不同类型,最简单实现就是弄个 map 保存字段映射关系,然后处理
然后伴随着业务的发展,不同类型需要处理,部分字段需要忽略,每次反射拿字段拿方法效率不行要缓存…最后就自己实现了一个 copy 库
zero47
2023-11-14 09:03:24 +08:00
让 A 给 B 做构造入参
zhangqian99
2023-11-14 09:04:14 +08:00
@chendy 想写一个工具类,使用注解的方式,有没有好的思路
aosan926
2023-11-14 09:09:31 +08:00
参考序列化与反序列化?
jsboy
2023-11-14 09:10:17 +08:00
java 的话,直接 mapstruct 吧,别重复造轮子了。
sumarker
2023-11-14 09:10:35 +08:00
不管是怎样映射关系总是需要维护的:
1.通过自定义注解,写在属性上,然后反射解析到对应的类属性上
2.搞一个中间类处理
3. 把映射关系,存在 xml 或者数据库里
dc2002007
2023-11-14 09:16:58 +08:00
搞 java 的总是喜欢把一些很简单的东西提出来讨论
looo
2023-11-14 09:36:45 +08:00
写这代码,还不如老老实实去手动 get set 装个插件一件生成 set 方法。

搞 copy 都是脱裤子放屁💨,有那时间早 set 好了。
theniupa
2023-11-14 09:41:02 +08:00
有那时间早 set 好了+1
SirYuxuan
2023-11-14 09:43:56 +08:00
```
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
2023-11-14 09:45:32 +08:00
重复造的轮子对比 mapstruct 有什么优势呢
SirYuxuan
2023-11-14 09:47:56 +08:00
不太明白为啥一点技术的氛围都没有呢,都会说在造轮子,up 说不定只是想学习一下实现的思路呢,技术无罪
zhangqian99
2023-11-14 09:51:28 +08:00
@Plutooo 这个是外包项目,在甲方虚拟机离线环境下编程,没有办法
yazinnnn0
2023-11-14 10:32:48 +08:00
https://github.com/mapstruct/mapstruct

从最早的 commit 看, 抄过来用用
yazinnnn0
2023-11-14 10:35:08 +08:00
另外, 离线开发都没有给 mvn 仓库镜像吗? 难道要手搓 framework?
Navee
2023-11-14 10:45:41 +08:00
'''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
2023-11-14 10:46:50 +08:00
@zhangqian99 #3 那你好像已经把答案说出来了…
注解的方式不一定最优,因为需要处理的逻辑量更大,如果要转换的东西本来就不多,那直接反射更方便
其实还有一些办法比如生成 get set 代码之类的,差别其实不大
另外如果是甲方离线环境…如果有入口的话直接把 mapstruct 或者其他库的 jar 包传进去配到依赖里也行
lyxeno
2023-11-14 11:29:46 +08:00
get set 好了,方便 IDE 重构和分析。
gabon
2023-11-14 13:17:58 +08:00
不要用反射,离线环境考虑把 mapstruct 的 jar 包打到 classpath 里
xuanbg
2023-11-14 13:25:31 +08:00
通用的话就是加注解,然后自己写个静态方法调用就成。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/991667

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX