You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过泛型从父类Person创建指定母国的子类实例?

解决方案:基于母国动态创建对应Person子类

1. 完善子类构造,固化母国值

先把子类的母国值在构造方法里固定,避免重复设置:

@Data
public class Norwegian extends Person {
    public Norwegian() {
        setMotherland(Country.NORWAY); // 若Country是字符串类型,直接传"Norway"
    }
}

@Data
public class Portuguese extends Person {
    public Portuguese() {
        setMotherland(Country.PORTUGAL);
    }
}

2. 实现映射工厂类

创建工厂类,通过母国和子类的映射关系,动态生成对应子类实例:

public class CitizenFactory {
    // 维护母国到子类的映射表
    private static final Map<Country, Class<? extends Person>> CITIZEN_TYPE_MAP = Map.of(
        Country.NORWAY, Norwegian.class,
        Country.PORTUGAL, Portuguese.class
    );

    @SuppressWarnings("unchecked")
    public static <T extends Person> T createCitizen(Person basePerson) throws Exception {
        Class<? extends Person> targetClass = CITIZEN_TYPE_MAP.get(basePerson.getMotherland());
        if (targetClass == null) {
            throw new IllegalArgumentException("无法识别的母国:" + basePerson.getMotherland());
        }

        // 创建子类实例
        T citizen = (T) targetClass.getDeclaredConstructor().newInstance();
        // 复制原Person的属性(如果属性多,用BeanUtils更高效)
        citizen.setName(basePerson.getName());
        // 母国已在子类构造中设置,无需重复赋值
        return citizen;
    }
}

如果属性数量多,推荐用Spring的BeanUtils.copyProperties(basePerson, citizen)替代手动赋值,减少冗余代码。

3. 修改泛型服务方法

调整getCitizen方法,结合工厂实现动态返回对应子类:

@Inject
@RestClient
PopulationInfoClient populationInfoClient;

public <T extends Person> T getCitizen(String personId) throws Exception {
    Person rawPerson = this.populationInfoClient.search(personId);
    return CitizenFactory.createCitizen(rawPerson);
}

补充说明

  • 如果Country是字符串而非枚举,只需把映射表的key改成字符串(比如"Norway")即可适配。
  • 异常处理可根据业务需求调整,比如返回默认Person实例、抛出自定义业务异常等。

内容的提问来源于stack exchange,提问作者Ekaterina Anisova

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 16:17:52