0

我想知道是否有从 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 表达式有什么好处吗?

4

2 回答 2

1

移动此代码并使用 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不添加任何信息。你可能想问一个关于你的数据结构的新问题。

于 2019-03-31T14:37:14.077 回答
1

有什么反对这样做的吗?

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

switch 表达式是一个poly 表达式如果目标类型已知,则此类型会被下推到每个 arm中。

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

将上述内容保持为真,您编写的 switch 表达式的类型可能是一个Object,除非您专门形成了一个自定义模型并封装了这些类型。

于 2019-03-11T02:11:31.183 回答