Java如何实现同名实例变量支持多类型且实例可存入同一ArrayList
可行实现方案
下面给两种符合要求的类型安全实现,都可以避免使用List<Object>的不良实践:
方案1:泛型实现(最优解)
将Test类定义为泛型类,成员变量a的类型随实例场景动态确定,代码示例如下:
public class Test<T> { private T a; private String b; // 构造String类型a的实例 public Test(String a, String b) { super(); this.a = (T) a; } // 构造double类型a的实例 public Test(Double a, String b) { super(); this.a = (T) a; } public T getA() { return a; } public String getB() { return b; } }
使用时声明List<Test<?>>类型的集合即可同时存储两种类型的Test实例,读取a时通过instanceof判断类型后再处理即可,编译阶段就能做基础类型校验,比List<Object>安全度高很多。
方案2:Object存储+类型标记(兼容原有代码)
如果不想修改原有代码对Test类的引用,可直接将a的类型改为Object,额外增加类型标记字段避免运行时类型转换异常:
public class Test { private Object a; private String b; private Class<?> aType; public Test(String a, String b) { super(); this.a = a; this.aType = String.class; } public Test(double a, String b) { super(); this.a = a; this.aType = double.class; } // 类型安全的a值读取方法 public String getAAsString() { if (!String.class.equals(aType)) { throw new UnsupportedOperationException("当前实例a不为String类型"); } return (String) a; } public double getAAsDouble() { if (!(double.class.equals(aType) || Double.class.equals(aType))) { throw new UnsupportedOperationException("当前实例a不为double类型"); } return (double) a; } public boolean isStringTypeA() { return String.class.equals(aType); } public String getB() { return b; } }
该方案不需要修改原有集合的声明,原来的List<Test>可直接使用,内置的类型判断方法可以避免业务代码出现无感知的类型转换错误。
不推荐的替代做法:将double转为String存入原
a字段,后续使用时再转回来,该方案会存在精度丢失、格式转换异常的风险,仅建议临时调试时使用。
内容的提问来源于stack exchange,提问作者nsa
相关产品推荐
相关产品推荐

