如何将多类型输入(字符串/整数/日期/列表)存入单个Java变量?
在UI中需支持条件选择,根据所选条件提供对应输入,输入类型包含QUANTITY、DATE、AMOUNT、LIST(多选列表)、RANGE(最小值和最大值),选择后将生成为JSON格式数据。现有Java类包含condition、value、valueList、valueType、minValue、maxValue字段及对应的getter和setter,不同输入类型的JSON示例如下:
AMOUNT类型示例:
{ "condition": "Basket Value", "value": "5", "dataType": "AMOUNT" }
RANGE类型示例:
{ "condition": "Percentile", "dataType": "RANGE", "minValue": 10, "maxValue": 60 }
LIST类型示例:
{ "condition": "Options", "dataType": "LIST", "valueList": ["option1", "option2"] }
现希望用单个变量替代value、valueList、minValue、maxValue这些字段,请问如何实现?使用Object类型是否为最优方案?还有其他可行方案吗?注:无法在Java中使用var关键字,最终数据将存储到MongoDB。
一、Object类型的实现方式
直接把原有分散的字段替换成一个Object类型的字段(比如命名为payload),根据dataType的不同赋值对应结构:
- AMOUNT、QUANTITY、DATE类型:给
payload赋值单个字符串/数值(如AMOUNT对应的"5") - LIST类型:赋值为
List<String>(如["option1", "option2"]) - RANGE类型:赋值为包含
minValue和maxValue的自定义对象或Map<String, Number>
这种方式实现简单,无需大量修改代码,MongoDB也能兼容存储,但缺点很明显:编译期无类型检查,使用时必须强制类型转换,极易出现ClassCastException,代码可读性和维护性差,并非最优方案。
二、更优的替代方案
1. 泛型类+自定义值类型
定义泛型基础条件类,同时针对不同输入类型创建专属值对象:
// 枚举定义所有数据类型 public enum DataType { QUANTITY, DATE, AMOUNT, LIST, RANGE } // 泛型基础条件类 public class Condition<T> { private String condition; private DataType dataType; private T payload; // getter、setter方法 } // RANGE类型专属值对象 public class RangeValue { private Number minValue; private Number maxValue; // 构造方法、getter、setter }
使用示例:
- AMOUNT类型:
Condition<String> amountCond = new Condition<>(); amountCond.setPayload("5"); amountCond.setDataType(DataType.AMOUNT); - RANGE类型:
Condition<RangeValue> rangeCond = new Condition<>(); rangeCond.setPayload(new RangeValue(10, 60)); - LIST类型:
Condition<List<String>> listCond = new Condition<>(); listCond.setPayload(Arrays.asList("option1", "option2"));
该方案保留编译期类型检查,代码安全性高,MongoDB可正常存储对应JSON结构,是兼顾改造成本和可维护性的推荐方案。
2. 用Map<String, Object>作为统一字段
将统一字段定义为Map<String, Object> payload,根据dataType存入对应键值对:
- AMOUNT类型:
payload.put("value", "5"); - RANGE类型:
payload.put("minValue", 10); payload.put("maxValue", 60); - LIST类型:
payload.put("valueList", Arrays.asList("option1", "option2"));
这种方式能保留原有JSON的字段结构,适配MongoDB存储,但同样存在类型安全问题,使用时需判断键存在性并做类型强转。
3. 多态子类实现
定义抽象父类,针对每种数据类型实现子类:
public abstract class BaseCondition { private String condition; private DataType dataType; // getter、setter方法 } public class AmountCondition extends BaseCondition { private String value; public AmountCondition() { setDataType(DataType.AMOUNT); } // getter、setter方法 } public class RangeCondition extends BaseCondition { private Number minValue; private Number maxValue; public RangeCondition() { setDataType(DataType.RANGE); } // getter、setter方法 } public class ListCondition extends BaseCondition { private List<String> valueList; public ListCondition() { setDataType(DataType.LIST); } // getter、setter方法 }
该方案完全保证类型安全,每个子类只维护自身所需字段,可读性强。但需配置MongoDB的多态识别字段(如_class),确保从数据库读取时能正确反序列化为对应子类。
总结
如果追求快速实现且能接受类型不安全风险,Object或Map方案可临时使用;若要兼顾类型安全和代码可维护性,泛型+自定义值类型或多态子类是更优选择,其中泛型方案代码侵入性更小,更适合现有代码的改造。
内容的提问来源于stack exchange,提问作者rma_ranasinghe

