应该remove(Object)被remove(?super E) - java

在this answer中,我试图解释为什么addadd(E)时Collection方法remove具有签名remove(Object)的原因。我想到了正确的签名应该是

public boolean remove(? super E element)

并且由于这在Java中是无效的语法,因此他们必须坚持使用Object,对于任何super E来说,恰好是EE的超类型)。以下代码解释了为什么这样做有意义:

List<String> strings = new ArrayList();
strings.add("abc");

Object o = "abc"; // runtime type is String
strings.remove(o);

由于运行时类型为String,因此成功。如果签名是remove(E),这将在编译时而不是在运行时导致错误,这没有任何意义。但是,以下内容会在编译时引发错误,因为该操作由于其类型而必定会失败,而这些类型在编译时是已知的:

strings.remove(1);

removeInteger用作参数,而不是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 - java

public 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 =…