java 反射 动态代码_java - 自动生成代码以动态创建Java对象(反射)。 - SO中文参考 - www.soinside.com...

使用 Reflection 你可以。调用 static newBuilder 方法来创建构建器。

查找所有 fieldssetters 对于特定 POJO 类。如果在所有情况下 setters 关于建筑商和 setters 关于 POJO 有相同的名称,就像你的例子一样,应该很容易转换。

调用 build 在建造者实例上创建新的 POJO.

使用基本 Java Reflection 和 Stream API-s,它可以像下面的样子。import java.lang.reflect.Method;

import java.util.Arrays;

import java.util.Properties;

import java.util.StringJoiner;

import java.util.function.Function;

import java.util.stream.Stream;

public class ReflectionApp {

public static void main(String[] args) throws Exception {

Properties properties = new Properties();

properties.put("name", "John");

properties.put("date", "today");

AvroPropertie manualInstance = AvroPropertie.newBuilder()

.setName(properties.getProperty("name"))

.setDate(properties.getProperty("date"))

.build();

Object dynamicInstance = AvroAutoCoder.createAndSet(AvroPropertie.class, properties::getProperty);

System.out.println(manualInstance);

System.out.println(dynamicInstance);

System.out.println("manualInstance == dynamicInstance => " + manualInstance.equals(dynamicInstance));

}

}

class AvroAutoCoder {

public static Object createAndSet(Class clazz, Function dataSupplier) throws Exception {

Object builderInstance = findMethod(clazz, "newBuilder")

.invoke(null);

Class> builderClass = builderInstance.getClass();

getSetters(clazz).forEach(setter -> {

try {

String fieldName = setter.getName().substring(3).toLowerCase();

findMethod(builderClass, setter.getName())

.invoke(builderInstance, dataSupplier.apply(fieldName));

} catch (Exception e) {

throw new IllegalStateException(e);

}

});

return findMethod(builderClass, "build")

.invoke(builderInstance);

}

private static Method findMethod(Class clazz, String methodName) {

return Arrays.stream(clazz.getDeclaredMethods())

.filter(method -> method.getName().equals(methodName))

.findFirst()

.orElseThrow(IllegalArgumentException::new);

}

private static Stream getSetters(Class clazz) {

return Arrays.stream(clazz.getDeclaredMethods())

.filter(method -> method.getParameterCount() == 1 && method.getReturnType() == Void.TYPE)

.filter(method -> method.getName().startsWith("set"));

}

}

上面的代码可以打印出来AvroPropertie[name='John', date='today']

AvroPropertie[name='John', date='today']

manualInstance == dynamicInstance => true

问题作者添加的注释。

在这个特定的例子中 APropertie 有一个静态的内部类,名为 Builder 其中持有想要的设置器。在这种情况下 getSetters() 方法需要稍微改变一下。// Find all setter of class

private static Stream getSetters2(Class clazz) {

Optional first = Arrays.stream(clazz.getDeclaredClasses())

.findFirst();

return Arrays.stream(first.get().getDeclaredMethods())

.filter(method -> method.getName().startsWith("set"));

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值