如何为Java中ImmutablePair创建支持String/Double的联合类型
解决方案:实现支持String/Double联合类型的参数列表
针对你的需求,我们可以通过以下几种方式在Java中实现类似联合类型(Sum Type)的结构,替换原有的List<ImmutablePair<Integer, String>>:
方案1:Java 16+ 密封类(Sealed Classes)实现类型安全的联合类型
密封类是Java 16引入的特性,天生适合定义联合类型,能在编译时确保所有类型分支都被处理,避免遗漏。
步骤1:定义密封接口作为联合类型
// 密封接口,限定只能由指定的子类实现 public sealed interface ParamValue permits ParamValue.StringValue, ParamValue.DoubleValue { // 内部记录类,存储String类型值 record StringValue(String value) implements ParamValue {} // 内部记录类,存储Double类型值 record DoubleValue(Double value) implements ParamValue {} }
步骤2:修改列表类型
将原有的列表类型替换为:
List<ImmutablePair<Integer, ParamValue>> params;
步骤3:使用时的类型处理
通过switch表达式(Java 14+)可以安全地处理两种类型,编译器会检查是否覆盖了所有分支:
for (ImmutablePair<Integer, ParamValue> pair : params) { Integer key = pair.getKey(); ParamValue value = pair.getValue(); String output = switch (value) { case ParamValue.StringValue sv -> String.format("Key %d: String值 - %s", key, sv.value()); case ParamValue.DoubleValue dv -> String.format("Key %d: Double值 - %.2f", key, dv.value()); }; System.out.println(output); }
方案2:兼容Java 16之前版本的标记接口方案
如果你的项目还在使用Java 16以下的版本,可以用标记接口+实现类的方式模拟联合类型:
步骤1:定义标记接口和实现类
// 标记接口,作为String/Double类型的共同父类 public interface ParamValue {} // 存储String值的实现类 public class StringParam implements ParamValue { private final String value; public StringParam(String value) { this.value = value; } public String getValue() { return value; } } // 存储Double值的实现类 public class DoubleParam implements ParamValue { private final Double value; public DoubleParam(Double value) { this.value = value; } public Double getValue() { return value; } }
步骤2:修改列表类型
同样替换为:
List<ImmutablePair<Integer, ParamValue>> params;
步骤3:使用时的类型处理
通过instanceof关键字判断类型,需要手动确保覆盖所有可能的实现类:
for (ImmutablePair<Integer, ParamValue> pair : params) { Integer key = pair.getKey(); ParamValue value = pair.getValue(); if (value instanceof StringParam stringParam) { System.out.printf("Key %d: String值 - %s%n", key, stringParam.getValue()); } else if (value instanceof DoubleParam doubleParam) { System.out.printf("Key %d: Double值 - %.2f%n", key, doubleParam.getValue()); } else { throw new IllegalArgumentException("不支持的参数类型: " + value.getClass().getName()); } }
方案3:自定义不可变Pair类(替代commons-lang3的ImmutablePair)
如果不想依赖第三方库,可以自己实现一个专门的不可变Pair类,封装联合类型的创建逻辑,让代码更简洁:
public sealed interface ParamValue permits ParamValue.StringValue, ParamValue.DoubleValue { record StringValue(String value) implements ParamValue {} record DoubleValue(Double value) implements ParamValue {} } // 自定义不可变参数Pair类 public final class ImmutableParamPair { private final Integer key; private final ParamValue value; private ImmutableParamPair(Integer key, ParamValue value) { this.key = key; this.value = value; } // 静态工厂方法,直接创建String类型的参数对 public static ImmutableParamPair ofString(Integer key, String value) { return new ImmutableParamPair(key, new ParamValue.StringValue(value)); } // 静态工厂方法,直接创建Double类型的参数对 public static ImmutableParamPair ofDouble(Integer key, Double value) { return new ImmutableParamPair(key, new ParamValue.DoubleValue(value)); } public Integer getKey() { return key; } public ParamValue getValue() { return value; } }
此时列表类型变为:
List<ImmutableParamPair> params;
使用时无需手动创建StringValue或DoubleValue实例,直接调用工厂方法:
params.add(ImmutableParamPair.ofString(1, "username")); params.add(ImmutableParamPair.ofDouble(2, 99.99));
内容的提问来源于stack exchange,提问作者halloleo
相关产品推荐
相关产品推荐

