如何正确地对此类进行通用以避免未经检查的警告?

时间:2018-04-09 13:37:57

标签: java generics

我有这个小类,它提供了一个可以抛出异常的东西的包装器并返回一个javaslang 2.05 Either(根据惯例,left中的失败和right中的正常结果。两者都可以只是其中之一。)

public class EitherWrapper {
    public static <E extends Exception, R> Either<E, R> wrap(Callable<R> callable) {
        try {
            return Either.right(callable.call());
        } catch (Exception e) {
            return (Either<E, R>) Either.left(e);
        }
    }
}

https://static.javadoc.io/io.javaslang/javaslang/2.0.5/javaslang/control/Either.html#left--

Either.left的Javadoc

问题是javac将return (Either<E, R>) Either.left(e);标记为未经检查的强制转换(这是javac认为它是Either<Exception,Object&gt;这是公平的)但我真的想要正确地修复它而不是仅仅强制转换它。我应该如何重写这个类,以便警告消失?

3 个答案:

答案 0 :(得分:2)

问题是你无论如何都要将Either.Left与异常挂钩,所以你没有达到泛型所允许的普遍性。

将其固定到Exception并完成以下操作:

public static <R> Either<Exception, R> wrap(Callable<R> callable) {
    try {
        return Either.right(callable.call());
    } catch (Exception e) {
        return Either.left(e);
    }
}

答案 1 :(得分:1)

使用type inference解析右侧部分的类型:

return Either.<E, R>left(e);

答案 2 :(得分:0)

因为我知道Either包裹了Exception我会这样做:

class EitherWrapper {
    public static <R> Either<Exception, R> wrap(final Callable<R> callable) {
        try {
            return Either.right(callable.call());
        } catch (final Exception ex) {
            return Either.left(ex);
        }

    }
}

没有必要将抛出的Exception生成为E,因为它的类型是在函数中明确定义的。

当然Either<? extends Exception, R>也可以。

使用例如

正确编译和运行
final Either<Exception, Object> e = EitherWrapper.wrap(Object::new);