一个引用链接列表的List变量

时间:2014-08-22 15:51:35

标签: java list exception

不确定我的标题是否足够具体。让我告诉你:

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。

这一切都正确吗?

2 个答案:

答案 0 :(得分:2)

  

首先,List没有类型,所以它如何添加一个String?所以它应该是:

private ArrayList<String> list;
     

所以第一个编译错误就是add方法

这是raw List,因此它与List<Object>类似,它可以接受Object的所有内容,而StringObject。您不应将其声明为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,对吧?

此处涵盖:What does it mean to "program to an interface"?

答案 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;
}