如何用@SuperBuilder和@Data访问作为其他类成员的子类属性?
解决Lombok @SuperBuilder场景下父类类型无法调用子类方法的问题
你的核心问题是City类中定义的Station是父类类型,实际存储的是子类PoliceStation实例,但编译器只识别父类类型,所以无法直接调用子类的特有方法。下面提供几种实用的解决思路:
1. 直接强制类型转换(快速解决)
因为你明确知道getCity()返回的City里的Station是PoliceStation实例,直接强转后就能调用子类方法:
public class Main { public static void main(String [] args) { City city = getCity(); // 强转后调用子类的set方法 ((PoliceStation) city.getStation()).setPoliceStationName("SFPD"); } }
如果存在Station是其他子类的可能,建议先做类型检查避免ClassCastException:
if (city.getStation() instanceof PoliceStation) { ((PoliceStation) city.getStation()).setPoliceStationName("SFPD"); }
2. 在City类中封装类型安全的方法
在City类里添加专门针对PoliceStation的操作方法,对外提供更友好的接口,同时内置类型检查:
@Data @SuperBuilder public class City { private String cityName; private Station station; // 封装设置警局名称的方法 public void setPoliceStationName(String policeStationName) { if (!(station instanceof PoliceStation)) { throw new IllegalArgumentException("当前城市的Station不是警局类型"); } ((PoliceStation) station).setPoliceStationName(policeStationName); } // 可选:封装获取警局名称的方法 public String getPoliceStationName() { return station instanceof PoliceStation ? ((PoliceStation) station).getPoliceStationName() : null; } }
之后在Main里直接调用即可:
public class Main { public static void main(String [] args) { City city = getCity(); city.setPoliceStationName("SFPD"); // 无需手动转换,直接调用 } }
3. 用泛型让City绑定特定Station子类
通过泛型约束City的Station类型,创建时指定具体子类,这样后续调用无需转换,完全类型安全:
// 修改City类为泛型类 @Data @SuperBuilder public class City<T extends Station> { private String cityName; private T station; } // 修改getCity方法,指定泛型类型 public static City<PoliceStation> getCity(){ return City.<PoliceStation>builder() .station(getPoliceStation()) .cityName("CityName") .build(); } // 在Main中使用 public class Main { public static void main(String [] args) { City<PoliceStation> city = getCity(); city.getStation().setPoliceStationName("SFPD"); // 直接调用子类方法,无编译错误 } }
这种方式适合业务逻辑中City的Station类型固定的场景。
4. 重构类结构(面向抽象编程)
如果Station的各个子类都有类似的“特有名称”属性,可以在父类中定义抽象方法,让子类实现,这样无需转换就能调用通用方法:
// 修改父类Station,添加抽象方法 @Data @SuperBuilder public abstract class Station { private String stationName; public abstract void setSpecificName(String name); public abstract String getSpecificName(); } // 子类PoliceStation实现抽象方法 @EqualsAndHashCode(callSuper = true) @Data @SuperBuilder public class PoliceStation extends Station{ private String policeStationName; @Override public void setSpecificName(String name) { this.policeStationName = name; } @Override public String getSpecificName() { return this.policeStationName; } }
之后在Main中直接调用父类的通用方法:
public class Main { public static void main(String [] args) { City city = getCity(); city.getStation().setSpecificName("SFPD"); // 父类方法调用,适配所有子类 } }
内容的提问来源于stack exchange,提问作者jgialis
相关产品推荐
相关产品推荐

