如何处理Collection中的返回类型中的泛型类型

时间:2018-07-20 11:58:47

标签: java java-8

在某些情况下,我必须根据条件返回两种不同类型的列表。但是它总是失败

public class App {

    public static void main(String[] args) {
        System.out.println(getData(true, Integer.class));
    }

    public static <E> List<E> getData(Boolean isLe, Class<E> clazz) {
        return isLe ? Arrays.asList(20) : Arrays.asList("test");
    }
}

错误:

Error:(18, 36) java: incompatible types: bad type in conditional expression
    inference variable T has incompatible bounds
      equality constraints: E
      lower bounds: java.lang.Integer

如何解决?

2 个答案:

答案 0 :(得分:3)

您不需要提供类来返回具有特定类型的通用List,但是如果您希望目标返回所需的类型,则需要使用目标的推断:

@SuppressWarnings("unchecked")
public static <T>  List<T> getData(Boolean isLe) {
    return isLe ? (List<T>)Arrays.asList(20) : (List<T>)Arrays.asList("test");
}

并使用它:

List<Integer> data = getData(true);

或:

System.out.println(getData(true);

但是由于客户端可能在目标中提供了不兼容的类型,因此此代码也破坏了通用安全性:

List<Integer> data = getData(false); 
// you will get a List of String that is stored in a List of Integer

因此您的要求似乎不一致。
客户端应确定List的通用类型,或者您调用的方法应确定该类型。但是两者都不是。
仅当类型从公共基类派生时,您的逻辑才有意义。在这种情况下,使用此基类的List作为泛型就足够了。
例如:

public static List<Number> getData(Boolean isLe) {
    return isLe ? Arrays.asList(20) : Arrays.asList(15F);
}

您可以致电:

List<Number> data = getData(false);

在您的情况下,该方法可能返回数字或字符串,因此您应将其基类用作泛型类型:Object

public static List<Object> getData(Boolean isLe) {
    return isLe ? Arrays.asList(20) : Arrays.asList(15F);
}

并调用它:

List<Object> data = getData(false);

但是现在,使用以Object键入的通用列表有什么优势?
没有人可以完成,您可能会通过在客户端代码中添加向下转换以在列表的元素上使用特定方法来完成。

答案 1 :(得分:1)

Boolean参数非常模糊,毕竟,您已经拥有clazz参数,比boolean更好地描述了预期结果,以及为什么用Boolean而不是{ {1}}?您是否要为此参数支持boolean值?

您可以将方法实现为

null

并像使用它

public static <E> List<E> getData(Class<E> clazz) {
    if(clazz == Integer.class) return Arrays.asList(clazz.cast(20));
    if(clazz == String.class) return Arrays.asList(clazz.cast("test"));
    throw new IllegalArgumentException(clazz+" is neither String nor Integer");
}

但是通常,我不建议使用这种设计。毕竟,尽管比猜测布尔参数的含义要好,但签名仍然不允许调用者识别出支持哪种类型的参数。