gpt4 book ai didi

java - 如何使用 lambda 表达式创建 'getter'

转载 作者:行者123 更新时间:2023-12-02 04:26:36 27 4
gpt4 key购买 nike

我的代码库中正在使用一个对象,UnsecureObject。该对象是自动生成的,没有 getter/setter,并且所有成员字段都是公共(public)的。因此,编辑是通过执行以下操作来完成的:

unsecureObjInstance.firstName = "Jane";

由于多种原因,这是不可取的,我可能不需要在这里解释。但是,使用这个生成的类需要我们的消息传递管道的一些其他技术细节,我不会讨论这些细节。

我希望利用我团队中其他人编写的映射实用程序将此 UnsecureObject 转换为我正在编写的 pojo。

实际映射器的示例(具有两个带 getter/setter 的普通类)如下所示:

new MapperBuilder<>(PojoOne.class, PojoTwo.class)
.from(PojoOne::getName).to(PojoTwo::getFirstName)
.build();

这会将 PojoOne#name 字段映射到 PojoTwo#firstName 字段。

有没有办法将其翻译为在此处输入我的UnsecureObject?我尝试过类似以下的方法:

new MapperBuilder<>(UnsecureObject.class, SecureObject.class)
.from(u -> u.firstName).to(SecureObject::getFirstName)
.build();

但是这里出现错误,无法调用类似于“u -> u.firstName”的内容。

所以问题是:

有没有一种方法可以使用这些公共(public)成员来动态地“构造” setter/getter ?因此,在 .from() 方法中,我可以构建看起来像标准方法的调用,该方法将生成我的 u.firstName?

感谢您的帮助!

编辑:

这大约是 MapperBuilder 类的样子(尝试进行一些编辑以去掉项目特定的包装器/简化)

/**
* This class is used to convert between POJO getter method references to the corresponding field names.
* @param <B> type
*/
public interface PojoProxy<B> {

/**
* Invokes the given getter method and returns information about the invocation.
* @param getter the getter to invoke
* @return information about the method invoked
*/
<T> GetterInvocation<T> invokeGetter(Function<B, T> getter);

}

/**
* Stores information about a method invocation.
* @param <T> method return type
*/
public interface GetterInvocation<T> {

public Class<T> getReturnType();

public String getFieldName();

}


/**
* A builder class to create {@link Mapper} instances.
* @param <FROM> source type
* @param <TO> target type
*/
public class MapperBuilder<FROM, TO> {

private final Class<FROM> _fromClass;
private final Class<TO> _toClass;
private final PojoProxy<FROM> _fromProxy;
private final PojoProxy<TO> _toProxy;

public MapperBuilder(Class<FROM> fromClass, Class<TO> toClass) {
_fromClass = fromClass;
_toClass = toClass;

//We will pretend there is an impl that provides the proxy.
//Proxies wrap the from and to classes in order to get reflection information about their getter calls.
_fromProxy = PojoProxy.of(fromClass);
_toProxy = PojoProxy.of(toClass);
}

public <FROM_VALUE> ToFieldBuilder<FROM_VALUE> from(Function<FROM, FROM_VALUE> getter) {
GetterInvocation<FROM_VALUE> methodInvocation = _fromProxy.invokeGetter(getter);
return new ToFieldBuilder<>(methodInvocation.getFieldName(), methodInvocation.getReturnType());
}

public class ToFieldBuilder<FROM_VALUE> {

private final String _fromFieldPath;
private final Class<FROM_VALUE> _fromClass;

public ToFieldBuilder(String fromFieldPath, Class<FROM_VALUE> fromClass) {
_fromFieldPath = fromFieldPath;
_fromClass = fromClass;
}

public <TO_VALUE> FromFieldBuilder<FROM_VALUE, TO_VALUE> to(Function<TO, TO_VALUE> getter) {
//similar to above, but now using a FromFieldBuilder.
}
}

public class FromFieldBuilder<FROM_VALUE, TO_VALUE> {

//impl..
}
}

最佳答案

我没有看到 MapperBuilder.from() 方法详细信息,您可以尝试 MapperBuilder.java 的实现 Function (getter) -> (BiConsumer) setter

public class MapperBuilder<S, D> {

private final S src;
private final D dest;

public MapperBuilder(S src, Class<D> dest) {
this.src = src;
try {
this.dest = dest.newInstance();
} catch (Exception e) {
throw new RuntimeException("Required default constructor for: " + dest);
}
}

//getter - function to get value from source instance
//setter - biConsumer to set value to destination instance
//example - map(SrcClass::getSrcValue, DestClass::setDestValue)
public <V> MapperBuilder<S, D> map(Function<S, V> getter, BiConsumer<D, V> setter) {
setter.accept(dest, getter.apply(src));
return this;
}

public D build() {
return dest;
}

}

SrcClass.java一些源类:

public class SrcClass {

private String srcValue;

public String getSrcValue() {
return srcValue;
}

public void setSrcValue(String srcValue) {
this.srcValue = srcValue;
}

}

DestClass.java一些目标类:

package com.example.demo;

public class DestClass {

private String destValue;

public String getDestValue() {
return destValue;
}

public void setDestValue(String destValue) {
this.destValue = destValue;
}

}

DemoApplication.java演示:

public class DemoApplication {

public static void main(String[] args) {

SrcClass src = new SrcClass();
src.setSrcValue("someValue");

DestClass dest = new MapperBuilder<>(src, DestClass.class)
.map(SrcClass::getSrcValue, DestClass::setDestValue)
// map another fields
.build();

// for your UnsecureObject case
UnsecureObject unsecureObject = new MapperBuilder<>(src, UnsecureObject.class)
.map(SrcClass::getSrcValue,
(unsecure, srcValue) -> unsecure.unsecureValue = srcValue)
.build();

}

}

关于java - 如何使用 lambda 表达式创建 'getter',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56606171/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com