不确定我的标题是否足够具体。让我告诉你:
class D {
private List list;
D() {
this.list = new LinkedList();
}
public LinkedList addHello() {
this.add("Hello");
return this.list;
}
}
我知道,因为LinkedList实现了List,我可以将LinkedList用于具有List类型的变量。现在我有一个方法返回"列表"在它添加"你好"它。
我对此感到有点困惑,但是当我看到两个可能的编译错误时,我想我是对的?首先,List没有类型,所以它如何添加一个String?所以它应该是:
private ArrayList<String> list;
所以第一个编译错误是add方法,第二个是方法addHello()返回类型为List的列表。
所以我的主要问题是:当你引用一个List变量,或者更多地说它时:如果你有一个接口,并且你将它用作变量然后你引用一个已经实现了接口的类( this.list = new LinkedList();),这并不意味着List在技术上成为了LinkedList,对吧?即使List引用了LinkedList,它也不会成为一个,我是对的吗?
因此该方法返回一个List,但它需要一个LinkedList。
这一切都正确吗?
答案 0 :(得分:2)
首先,List没有类型,所以它如何添加一个String?所以它应该是:
private ArrayList<String> list;
所以第一个编译错误就是add方法
这是raw List
,因此它与List<Object>
类似,它可以接受Object
的所有内容,而String
是Object
。您不应将其声明为ArrayList
,因为这是具体实施,而是保持List<String>
。如果你声明它是原始的,它不会引发编译器错误,而是一个警告。
现在,这段代码:
public LinkedList addHello() {
this.list.add("Hello");
return this.list;
}
这简直不会编译,因为你说你必须返回(原始)LinkedList
,而是返回(原始)List
。这是错误的,因为当您声明将返回更具体的类型时,您无法返回超类型。如果将这个例子移到水果上,它就像你的方法状态我总是会返回橙子但实现会返回一个水果,可能是苹果,草莓或任何不是橙色的东西
要解决此问题,只需更改返回类型:
public List addHello() {
this.list.add("Hello");
return this.list;
}
而且,正如@ElliotFrisch在他的回答中所述,只是不在代码中使用原始类型,而是添加通用检查以进行编译(因为at runtime it will be erased)。
如果你有一个接口,并且你将它用作变量然后你引用一个已经实现了接口的类(this.list = new LinkedList();),这并不意味着List在技术上变成了LinkedList,对吧?
答案 1 :(得分:0)
这是raw-type,您应该返回界面List
(就像您定义的list
引用一样)。像,
private List<String> list;
D() {
this.list = new LinkedList<>(); // <-- diamond operator
}
public List<String> addHello() { // return type.
this.add("Hello");
return this.list;
}