Java - 将字段值从字符串(反射)设置为正确的类型

ip6*_*696 5 java reflection

我有这样的课程:

public enum  Type {
    ONE, TWO
}

@Data
public class Car {
    private String name;
    private int year;
    private Type type;
}
Run Code Online (Sandbox Code Playgroud)

我有新对象:

Car car = new Car();
Run Code Online (Sandbox Code Playgroud)

我有这个数据:

Map<String, String> data....

name - BMW
year - 2018
type - TWO
Run Code Online (Sandbox Code Playgroud)

键和值 - 字符串

我需要将此值设置为对象(除了反射,我看不出有什么办法)

    Field year = car.getClass().getDeclaredField("year");
    year.setAccessible(true);
    year.set(car, data.get("year"));//2018 as string
Run Code Online (Sandbox Code Playgroud)

我得到异常(不同,我不知道):

Caused by: java.lang.IllegalArgumentException: Can not set int field com.example.mapper.Car.year to java.lang.String
Run Code Online (Sandbox Code Playgroud)

因此,问题是 - 如何正确地将值转换为要在字段中设置的所需类型?

这是一个简单的例子,因为真正的任务解释起来很长。简而言之 - 我得到一个值列表(它们始终是一个字符串)以及它们更改的字段名称(也是一个字符串),并且必须使用新值更新对象的字段

Nay*_*aya -2

我建议不要在任何可能的地方使用反射。就像你的具体例子一样。

您可以为 Car 类中的每个字段创建一个包含 BiConsumers 的枚举类:

import java.util.Map;
import java.util.function.BiConsumer;

@Data
public class Car {
    private String name;
    private int year;
    private Ttc.Type type;

    static enum CarEnum {
        name((car, value) -> car.setName(value)),
        year((car, value) -> car.setYear(Integer.parseInt(value))),
        type((car, value) -> car.setType(Ttc.Type.valueOf(value)));
        private BiConsumer<Car, String> setValueConsumer;

        CarEnum(BiConsumer<Car, String> setValueConsumer) {
            this.setValueConsumer = setValueConsumer;
        }

        static Car createCar(Map<String, String> data) {
            Car car = new Car();
            data.forEach((key, value) -> valueOf(key).setValueConsumer.accept(car, value));
            return car;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后以下面的方式使用它:

Map<String, String> data = new HashMap<>();
data.put("name", "BMW");
data.put("year", "2018");
data.put("type", "TWO");
Car.CarEnum.createCar(data);
Run Code Online (Sandbox Code Playgroud)