【问题标题】:Return generic value from switch expression in Java-12从 Java-12 中的 switch 表达式返回泛型值
【发布时间】:2019-08-01 05:55:27
【问题描述】:

我想知道是否有从 Java 12 switch 表达式返回泛型类型的选项。

基本代码如下所示:

boolean result = switch(ternaryBool) {
    case TRUE -> true;
    case FALSE -> false;
    default -> throw new IllegalArgumentException("Seriously?!");
};

有什么反对这样做的吗?

T result = switch(ternaryBool) {
    case TRUE -> BooleanUtils.toBoolean('true');
    case FALSE -> new Integer(0);
    default -> throw new IllegalArgumentException("Seriously?!");
};

编辑:

也许是我的案例中更好的例子:我需要几个代表原始和复杂数据结构的类。我还有一个工厂方法,它基于来自其他系统的枚举和未知值创建这个DataPointValue让我们忘记强制转换异常):

public static <T> IDataPointValue create(T value, DATA_TYPE dataType) throws Exception {
    try {
        switch (dataType) {
            case BOOL:
                return new BoolDataPointValue((Boolean) value);
            case INT:
                return new IntDataPointValue((Integer) value);
            case WORD:
                return new IntDataPointValue((Integer) value);
            case STRING:
                return new StringDataPointValue((String) value);
            case REAL:
            case FLOAT:
                return new RealDataPointValue((Float) value);
            case DINT:
                return new DIntDataPointValue((Integer) value);
            case DWORD:
                return new DWordDataPointValue((Integer) value);
            default:
                throw new Exception("Data Type not implemented: " + dataType);
        }
    } catch (ClassCastException e){
        throw new Exception("Could not create DPV in terms of Type incompability");
    }
}

移动这段代码并使用 Java 12 中的 switch 表达式有什么好处吗?

【问题讨论】:

  • 那不是真正的泛型类型是吗?泛型类型不会要求它们都返回相同的类型,只是它们返回的统一类型可以改变吗?你可以让它返回Object,然后整理出来。
  • 是的,这只是为了简化。当然,我在考虑更复杂的事情。
  • 也许您应该发布一个更能代表您所询问情况的示例。
  • 不推荐返回Object。您应该构建自己的层次结构并封装这些类中的所有值。完成后,您可以用超类替换子类。这样你也可以使用Dynamic binding(不需要instanceof操作符。
  • @KhanSaab 是的,Object 是一个糟糕的建议,但它比使用泛型更有意义。

标签: java generics switch-statement java-12 switch-expression


【解决方案1】:

有什么反对这样做的吗?

JEP 325: Switch Expressions (Preview) 在其中一列中说明了关于 switch 语句的扩展表示(格式化我的):

switch 表达式是一个 poly 表达式如果目标类型是 众所周知,这种类型被推入每个手臂

switch 表达式的类型是它的目标类型(如果已知); 如果不是,则通过组合每个案例臂的类型来计算独立类型。

假设上述情况为真,您编写的 switch 表达式的类型可能是 Object,除非您专门形成了自定义模型并封装了类型。

【讨论】:

    【解决方案2】:

    移动这段代码并使用java12中的switch表达式有什么好处吗?

    这实际上取决于您将什么视为利润。在查看相应的 switch 表达式时,您会立即想到几件事:

    public static <T> IDataPointValue create(T value, DATA_TYPE dataType) {
        return switch (dataType) {
            case BOOL ->        new BoolDataPointValue((Boolean) value);
            case INT ->         new IntDataPointValue((Integer) value);
            case REAL, FLOAT -> new RealDataPointValue((Float) value);
            // ...
        };
    }
    
    1. 您不需要 default 大小写,因为编译器知道您正在处理所有枚举值(运行时更改枚举会导致问题)。
    2. 因为您在整个表达式上 return 而不是在每个 case 中显式地使用它,所以它更具可读性,而且您不需要处理失败语义。

    至于问题的泛型方面,还不是很清楚。一方面,你的方法是无限制地声明一个遗传参数,并且只使用一次,所以它没有真正的意义。声明

    public static <T> IDataPointValue create(T value, DATA_TYPE dataType)
    

    相同
    public static IDataPointValue create(Object value, DATA_TYPE dataType)
    

    因为T 没有添加任何信息。您可能想就您的数据结构提出一个新问题。

    【讨论】:

      猜你喜欢
      • 2020-03-14
      • 2021-05-18
      • 2021-02-12
      • 2018-07-31
      • 2022-12-13
      • 1970-01-01
      • 1970-01-01
      • 2021-08-13
      • 1970-01-01
      相关资源
      最近更新 更多