List接口的lastIndexOf()方法接受类型为Object的参数。
但是,add()方法接受E类型的参数(这是在创建列表时定义的列表的泛型类型),因为add()只接受E,这阻止了开发人员(或用户)在编译时将任何不兼容的对象添加到列表中。
现在,Java doc指出,如果传递的对象不兼容,lastIndexOf()可以抛出ClassCastException。但是,当我在Eclipse Helios中运行以下代码时,我没有得到任何异常:
package scjp.collection.list;
import java.util.ArrayList;
import java.util.List;
public class LastIndexOf {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("some");
list.add("thing");
list.add("at");
list.add("last");
list.add("and");
list.add("at");
list.add("again");
System.out.println(list.lastIndexOf("at"));
System.out.println(list.lastIndexOf(10)); // # 1
System.out.println(list.lastIndexOf(new LastIndexOf())); // # 2
}
}在第1行和第2行,我将不兼容的对象传递给了类型为String的列表。但是,我得到的输出是:-
5
-1
-1我得不到ClassCastException。
如果lastIndexOf()方法接受的是E类型的对象,而不是Object类型的对象,那么这只会在编译时被阻止。为什么不这样做呢?
Java创建者一定考虑到了如果它接受E(而不是Object)可能会出现的问题。这会有什么害处??
发布于 2012-01-31 15:57:21
这里有一个可能会有所帮助的例子。请注意,如果传递一个具有相同顺序的相等元素的LinkedList<T>,则ArrayList<T>使用的equals方法将返回true。所以,如果你有一个List<ArrayList<Integer>>,为了找到一个相等的ArrayList<Integer>,在它上面调用lastIndexOf,传递一个LinkedList<Integer>是有效的。但是,如果lastIndexOf是按照您所描述的方式定义的,这是不可能的。
发布于 2012-01-31 15:50:24
您不需要E类型--请记住,泛型只是类型转换的检查糖,而equals是在Object上定义的,因此您不需要强制转换项来确定它是否等于列表中的其他项。另外,考虑有界通配符的使用。如果您的列表被定义为List<? extends Foo>,那么您将无法获得除null之外的任何项目的lastIndexOf。
发布于 2012-01-31 16:00:42
原因与Collection.remove(对象o)具有类似签名的原因相同。有关更多详细信息,请参阅this question。
https://stackoverflow.com/questions/9075993
复制相似问题