【问题标题】:Java Method declaration returning List Generics with referenceJava 方法声明返回 List 泛型和引用
【发布时间】:2017-12-29 16:28:49
【问题描述】:

你能解释一下为什么第一个不起作用吗?

import java.util.ArrayList;
import java.util.List;

public class MyClass {

    private <T extends Object> List<Class<T>> getList1() {
        return new ArrayList<>();
    }

    private <T extends Object> List<Class<T>> getList2(Class<T> cls) {
        List<Class<T>> list = new ArrayList<>();
        list.add(cls);
        return list;
    }

    private List<Class<? extends Object>> getList3() {
        return new ArrayList<>();
    }

    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        // 1. Not OK - The method add(Class<Object>) in the type List<Class<Object>> is not applicable for the arguments (Class<String>)
        myClass.getList1().add(String.class);
        // 2. OK
        myClass.getList2(String.class);
        // 3. OK
        myClass.getList3().add(String.class);
    }

}

我认为getList1() 正在返回从Object 扩展的类的List,而String 就是其中之一?

不,这不是一个重复的问题(至少不是被链接的问题)。如果我真的定义了一个对象列表,当然我不希望它采用一个字符串列表。但是在这里我接受一个对象列表以及从对象扩展的对象,所以问题是为什么它在第一种情况下不接受字符串。

【问题讨论】:

标签: java list generics


【解决方案1】:

你可以这样调用方法:

myClass.<String>getList1().add(String.class);

不知何故,编译器需要知道您的T 应该是什么(&lt;String&gt; 称为type witness)。


  • 使用您的方法getList2(String.class),您可以通过传入参数来指定它。
  • 使用您的方法getList3(),声明本身使用通配符(?),因此您不必指定T,但您的列表不会是强类型(它将接受每个扩展Object的类) .

【讨论】:

  • 哇,以前从未见过。这个&lt;String&gt; 是从哪里来的?而且我认为编译器可以从我上次的add(String.class)?
  • 看这里(尤其是关于类型见证的部分):docs.oracle.com/javase/tutorial/java/generics/…
  • 谢谢。我查看了您建议的页面,但仍然不确定为什么第一种方法没有编译。特别是在页面的最底部,它说 J8 中不再需要类型见证,其中编译器可以从参数推断类型。所以.add(String.class) 应该将T 推断为String,因此在getList1() 中使用相同的T = String,不是吗?
  • 我明白你的意思,我必须诚实地承认我并不完全知道答案。出于个人兴趣,我发布了一个后续问题:stackoverflow.com/questions/45294380/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-30
  • 1970-01-01
  • 2013-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多