【问题标题】:Generic method with genric argument and return type具有泛型参数和返回类型的泛型方法
【发布时间】:2018-01-16 09:44:38
【问题描述】:

我想创建一个泛型方法,其返回类型包含发送到该方法的泛型元素。 只要输入参数的类型与泛型类型完全相同,这就可以正常工作。但是我希望可以发送泛型类型的扩展。

基本上,我想创建一个方法,createList,它适用于这两个调用:

List<Object> list = createList("foo");
List<String> list2 = createList("bar");

下面的这个通用方法适用于第二次调用,但不适用于第一次。

private static <T> List<T> createList(T element) {
    List<T> list = new ArrayList<>();
    list.add(element);
    return list;
}

对于第二次调用,我收到一个编译错误,提示“不兼容的类型。必需的对象。找到的字符串”。

以下是非通用版本,第一次调用时效果很好,但第二次调用时就不行了:

private static List<Object> createList(Object element) {
    List<Object> list = new ArrayList<>();
    list.add(element);
    return list;
}

这里的编译错误与其他版本相同,但这次需要 String,并且找到了 Object。

是否可以创建一个方法(最好使用泛型)以使这两个调用都有效? (使用 Java 7)

【问题讨论】:

  • 您还没有编写自己的名为Object 的类吗?或者从某个奇怪的库中导入了Object 类?您的编译错误表明这里的Object 没有通常的定义。
  • 你可以只投射到对象:createList((Object)"foo")
  • 我可以使用 Java 7 重现,但这在 Java 8 中运行良好。所以答案是更新。
  • @DawoodibnKareem 不,它是标准的 Java 对象 (java.lang.Object)。
  • @JornVernee 我需要它来使用 Java 7。

标签: java generics


【解决方案1】:

Java 8 中的一些类型推断更改解决了这个问题。所以直接的解决方案是更新。

如果您不能或不想更新到 Java 8,您也可以显式提供泛型类型:

List<Object> list = EnclosingClass.<Object>createList("foo");

其中EnclosingClass 是声明createList 的类。

【讨论】:

  • 谢谢,提供泛型类型可以完美运行。 (我无法更新到 Java 8)
【解决方案2】:

我正在做类似的事情,并使用这样的方法解决了问题。

此外,这不限于任何特定的“类型”元素。它允许每个对象和/或原语。 IT 还为您提供了一个单行字,可以用一些元素填充已创建的列表。

    @SafeVarargs
    private static <T extends Collection<S>, S> T makeList(T collection, S... objects) {
        Collections.addAll(collection, objects);
        return collection;
    }

   //example:
   List<String> list1 = makeList(new LinkedList<String>(), "foo", "bar");
   List<Integer> list2 = makeList(new ArrayList<Integer>(), 1,2,3,4);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-24
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    相关资源
    最近更新 更多