在this answer中,我试图解释为什么add
是add(E)
时Collection方法remove
具有签名remove(Object)
的原因。我想到了正确的签名应该是
public boolean remove(? super E element)
并且由于这在Java中是无效的语法,因此他们必须坚持使用Object
,对于任何super E
来说,恰好是E
(E
的超类型)。以下代码解释了为什么这样做有意义:
List<String> strings = new ArrayList();
strings.add("abc");
Object o = "abc"; // runtime type is String
strings.remove(o);
由于运行时类型为String,因此成功。如果签名是remove(E)
,这将在编译时而不是在运行时导致错误,这没有任何意义。但是,以下内容会在编译时引发错误,因为该操作由于其类型而必定会失败,而这些类型在编译时是已知的:
strings.remove(1);
remove
将Integer
用作参数,而不是super String
,这意味着它实际上从不删除集合中的任何内容。
如果remove
方法是用参数类型? super E
定义的,则编译器可能会检测到上述情况。
题:
我的理论是否正确,即remove
应该具有一个反变的? super E
参数而不是Object
,以便编译器可以滤除上面示例中所示的类型不匹配? Java Collections Framework的创建者选择使用Object
而不是? super E
是正确的,因为? super E
会导致语法错误,并且他们没有同意使通用系统复杂化,他们只是同意使用Object
而不是super
?
另外,removeAll
的签名应为
public boolean removeAll(Collection<? super E> collection)
请注意,我不想知道为什么签名不是remove(E)
,这是在this question中进行询问和解释的。我想知道remove
是否应为协变(remove(? super E)
),而remove(E)
表示协方差。
一个不起作用的示例如下:
List<Number> nums = new ArrayList();
nums.add(1);
nums.remove(1); // fails here - Integer is not super Number
重新考虑我的签名,它实际上应该允许E
的子类型和超类型。
参考方案
这是一个错误的假设:
因为该操作由于其类型而必定会失败,而这些类型在编译时是已知的
与.equals
接受对象的理由相同:对象不一定要具有相同的类才能相等。请考虑以下示例,该示例具有List的不同子类型,如the question @Joe linked中所指出:
List<ArrayList<?>> arrayLists = new ArrayList<>();
arrayLists.add(new ArrayList<>());
LinkedList<?> emptyLinkedList = new LinkedList<>();
arrayLists.remove(emptyLinkedList); // removes the empty ArrayList and returns true
您提议的签名将无法实现。
Java-如何遍历ArrayList以添加元素? - java我是java的新手,我想从一个类中获取所有数据。这是我向类添加数据的方式:String[] arrNames = { "Andrew", "James" ... }; ... for(int i = 0; i < arrNames.length; i++){ Person person = new Person(…
等待和等待时间差异? - java我在一次采访中遇到了这个问题。线程中的wait和wait on time有什么区别?我知道wait方法使当前线程等待,直到另一个线程为此对象调用notify()方法或notifyAll()方法,或者经过了指定的时间。但是我不确定他在问什么准时。谁能解释一下等待时间是什么意思?提前致谢。 参考方案 它们可能表示Object.wait(long timeout)…
如何将对象转换为长数据类型Java - java我有这段代码,给我一个错误?public int part(Object key) { long clientId = (long) key; ... } 下面是错误:java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long 不知道为什么会引发异常。 参考…
对象比较是否相等:JAVA - javapublic ClassA { private String firstId; private String secondId; public void setFirstId(String firstId) { this.firstId = firstId; } public String getFirstId() { return id; } public…
从对象转换为原始类 - java我将Entry类的实例存储在Object中。Entry newentry = new Entry(j, 0.0); Object test = newentry; 如何将test对象转换回Entry类以访问Entry类方法getValue()? 参考方案 输入它:Entry newentry = new Entry(j, 0.0); Entry test =…