为什么不需要声明List实现?

时间:2015-06-26 21:31:41

标签: java list interface spotify

我正在使用返回类型if (this.props.pieces && this.props.onDeletePiece2) { var that = this; var pieces = that.props.pieces.map( function(piece, i) { return ( <Piece pieceData={piece} onDeletePiece3={that.props.onDeletePiece2} key={i}/> ) }) 的方法,然后我可以调用... 上的方法:

List<>

要清楚List返回类型List<Artist> artists = artistsPager.artists.items; artists.add(new Artist());

由于artistsPager.artists.items只是一个接口,编译器如何让我使用这个List<Artist>对象,List总是不需要实现,如artists

例如,编译器不允许我执行以下操作,因为“List是抽象的;无法实例化”:

List<>

ArrayListList<Integer> list = new List<Integer>(); 有什么不同?

对于那些好奇的人来说,这来自Java Web API wrapper for Android。非常感谢所有帮助。

我不相信这是question的重复,因为尽管答案是相同的,但产生这些答案的问题却是不同的。另一个问题是询问类型artistsPager.artists.itemsnew List<Integer>()之间的区别,而我的问题是想知道为什么编译器在List的实现被隐藏时没有抱怨。

我很好地将此标记为重复,以指示未来的用户使用该问题,但我不认为它应该被关闭,因为我认为这些答案对其他用户非常有帮助。

3 个答案:

答案 0 :(得分:3)

  

artistsPager.artists.items与new List<Integer>()有什么不同?

artistsPager.artists.itemsList<>类型的字段。在代码的某处,它必须使用ArrayList等具体实现进行实例化。

new List<Integer>()是一个构造函数调用,因为List是一个接口而无效。

答案 1 :(得分:2)

  

并非List<>始终需要实施,例如ArrayList<>

是的,您需要一个实现才能创建实例。但是,编译器知道两件事:

  • 它知道您已经创建了某些实例,并将其分配给items
  • 它知道您分配给items的任何内容,实现List<>接口

知道这两件事就足以让编译器让你在声明为接口类型的变量上调用add。通过这种方式您的代码无需关心您获得的实现 - ArrayList<>LinkedList<>或您开发的某些自定义实现:您的代码将适用于所有它们。

请注意,通过接口类型引用对象的做法是可取的。它被称为编程接口。它允许您隐藏实现细节,并在以后交换不同实现的对象。

答案 2 :(得分:0)

这意味着在某处创建了一个具体列表(例如,ArrayList)。

您只知道创建的列表是从List接口实现方法,允许您使用这些方法。

以此示例隐藏用户的具体LinkedList

public static List<Integer> makeListOfInts(){
    return new LinkedList<Integer>(){
        {
            add(1);
            add(2);
        }
    }
}

我可以很容易地用ArrayList替代:

public static List<Integer> makeListOfInts(){
    return new ArrayList<Integer>(){
        {
            add(1);
            add(2);
        }
    }
}

并且所有函数的用户都知道返回List,但它不知道列表的具体类型。它可能只使用List接口中的函数,而不是来自所选的特定实现。