优化泛型<T>对象构建:如何避免传入builder参数?
优化类型对象构建的方案
针对你提出的问题,这里有两种无需传入builder参数、且对不可变对象友好的实现方案,均无需强制类型转换:
方案1:让父接口定义类型安全的构建方法
这是最推荐的方案,通过在FourVector接口中定义泛型构建方法,让子类自行实现实例化逻辑,既保证编译期类型安全,又符合不可变对象的设计原则。
步骤1:修改FourVector接口为泛型接口
public interface FourVector<T extends FourVector<T>> { // 定义从组件映射构建实例的方法,子类需返回自身类型 T fromComponents(Map<Axis, Double> components); // 保留原有的asMatrix等方法 Matrix asMatrix(); }
步骤2:子类实现该构建方法
以MomentumVector为例(假设这是FourVector的子类):
public class MomentumVector implements FourVector<MomentumVector> { // 不可变字段 private final double t; private final double x; private final double y; private final double z; // 私有构造器,保证不可变性 private MomentumVector(Map<Axis, Double> components) { this.t = components.get(Axis.T); this.x = components.get(Axis.X); this.y = components.get(Axis.Y); this.z = components.get(Axis.Z); } @Override public MomentumVector fromComponents(Map<Axis, Double> components) { return new MomentumVector(components); } @Override public Matrix asMatrix() { // 实现矩阵转换逻辑 return Matrix.asMatrix(this); } }
步骤3:简化transformVector方法
现在可以直接通过输入对象调用构建方法,无需传入builder参数:
public <T extends FourVector<T>> T transformVector(T input, TransformInto direction) { Matrix input_matrix = input.asMatrix(); Matrix result = physicsMatrix(direction.sign()).times(input_matrix); // 直接调用input的fromComponents方法,返回类型自动匹配T return input.fromComponents(asComponents(result)); }
方案2:利用反射构建实例(备选方案)
如果无法修改FourVector接口,可通过反射获取输入对象的类信息,调用对应的构造器或静态工厂方法。这种方式无需修改子类接口实现,但会损失部分编译期类型安全,且存在一定性能开销。
修改后的transformVector方法
public <T extends FourVector> T transformVector(T input, TransformInto direction) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { Matrix input_matrix = Matrix.asMatrix(input); Matrix result = physicsMatrix(direction.sign()).times(input_matrix); Map<Axis, Double> components = asComponents(result); // 获取输入对象的类,反射调用接收Map参数的构造器 Constructor<T> constructor = (Constructor<T>) input.getClass().getConstructor(Map.class); return constructor.newInstance(components); }
注意:使用该方案时,所有
FourVector的子类必须提供接收Map<Axis, Double>参数的公共构造器,否则会抛出反射异常。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

