A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 冯鹏飞 黑马帝   /  2011-7-21 17:45  /  7670 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

对于ArrayList  l=new ArrayList()而言,l.subList()返回值类型怎么会是List而非ArrayList 呢?该函数不是求其子集的吗?

3 个回复

倒序浏览
subList()方法是接口List中定义的方法,返回值就是一个List类型,而ArrayList只是实现了List接口,本事并没有这个方法

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-7-21 20:52:32
藤椅
恩,LS说的很对!ArrayList本身没有提供subList这个方法,subList是List中的一个方法,但是Array实现了List接口!
ArrayList在JDK中的定义:[color=Red]Resizable-array implementation of the List interface.Implements all optional list operations, and permits all elements, including null.[/color] In addition to implementing the List interface, this class provides methods to manipulate the size of the array that is used internally to store the list.

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
看了上面两位的回答,补充一下。
类实现接口,List有subList()方法(返回值为List),实现类完全可以实现它并且返回List的实现类的。就是说ArrayList的subList()方法是可能做到的(但是SUN没有这么做)。

而且ArrayList的subList是来继承自于AbstractList的(本身没有,是AbstractList实现的。而且ArrayList又实现了List)。List和AbstractList都有subList()方法(而且AbstractList实现了List,也(要说“也”,是因为AbstractList是抽象类,抽象类不实现接口的方法也可以)实现也subList方法,从下面的代码可以看出)
类树形结构:
java.lang.Object
  java.util.AbstractCollection<E>
      java.util.AbstractList<E>
        java.util.ArrayList<E>
我这样做[code=java] ArrayList list = new ArrayList();
转换异常:
java.util.RandomAccessSubList cannot be cast to java.util.ArrayList
所以subList返回的是RandomAccessSubList,奇怪?看源代码,因为ArrayList继承自AbstractList,而且也没有覆盖subList()方法,所以到AbstractList中找:

                list.add("wang");
                list.add("liang");
                list.add("hello world");
                ArrayList list2= (ArrayList) list.subList(0, 1);[/code]转换异常:
java.util.RandomAccessSubList cannot be cast to java.util.ArrayList

所以subList返回的是RandomAccessSubList,奇怪?看源代码,因为ArrayList继承自AbstractList,而且也没有覆盖subList()方法,所以到AbstractList中找:[code=java]public List<E> subList(int fromIndex, int toIndex) {
        return (this instanceof RandomAccess ?
                new RandomAccessSubList<E>(this, fromIndex, toIndex) :
                new SubList<E>(this, fromIndex, toIndex));
}[/code]看到方法中又多出两个类RandomAccessSubList和SubList,它们在哪里?原来是和AbstractList类所在文件中(class SubList<E> extends AbstractList<E>,而class RandomAccessSubList<E> extends SubList<E> implements RandomAccess)
而ArrayList实现了RandomAccess,所以list.subList(0, 1)返回的是 RandomAccessSubList,显然不能转换。

List的实现类LinkedList也是类似,但是它没有实现RandomAccess,所以猜想上面的代码换成LinkedList也会出现异常,而且应该是SubList不能转换成LinkedList。[code=java]                LinkedList list = new LinkedList();
                list.add("wang");
                list.add("liang");
                list.add("hello world");
                LinkedList list2 = (LinkedList) list.subList(0, 1);[/code]确实java.util.SubList cannot be cast to java.util.LinkedList

为啥SUN将ArrayList的subList()的返回值搞成List?这是面现接口编程。List是个接口,不必关心子类(就是实现类)的具体行为。List只提供一个统一的“接口”(不是interface)就行了。面向接口编程似乎有人问了,网上也有资料,它的好处不是一两句话能说的清楚的。

评分

参与人数 1技术分 +2 收起 理由
小龙 + 2 不错!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马