Java 为什么';JDK Collections.distinct是否强制这些参数包含相同的元素类型?

Java 为什么';JDK Collections.distinct是否强制这些参数包含相同的元素类型?,java,types,Java,Types,这个方法很简单 我预计以下代码会导致类型错误: List<String> ls = new ArrayList<>(); List<Integer> li = new ArrayList<>(); boolean result = Collections.disjoint(ls, li); List ls=new ArrayList(); List li=new ArrayList(); 布尔结果=集合。不相交(ls,li); 然而,事实并非如

这个方法很简单

我预计以下代码会导致类型错误:

List<String> ls = new ArrayList<>();
List<Integer> li = new ArrayList<>();
boolean result = Collections.disjoint(ls, li);
List ls=new ArrayList();
List li=new ArrayList();
布尔结果=集合。不相交(ls,li);
然而,事实并非如此,也将永远如此。
为什么它会允许这样做?

我不知道这个决定背后的确切原因。但是,它允许一些非常有用的行为,例如比较一组
Foo
和一组
Bar扩展Foo
的不相交性。通配符类型是允许这样做的方式。

我看不出有什么奇怪的地方。想想Java中的相等是在对象之间表示的,您有
布尔相等(Object other)
而不是
布尔相等(T other)

既然
equals
确实用于查找两个集合是否不相交(或者在集合的情况下是
hashCode()
),为什么需要引发类型错误

根据这一观点,甚至

Set<Integer> set = new HashSet<Integer>();
boolean test = set.contains("foobar");
Set Set=newhashset();
布尔测试=set.contains(“foobar”);

应该被视为错误。

这里有一个更好的问题:为什么会这样

考虑
Foo扩展Bar
Bar扩展Jo
Blo扩展Jo
,然后:

List<Jo> jos = new ArrayList<Jo>();
List<Bar> bars = new ArrayList<Bar>();

//populate both lists arbitrarily

Collections.disjoint(jos, bars);
List jos=new ArrayList();
列表栏=新的ArrayList();
//任意填充两个列表
集合。不相交(jos,bar);

上面的调用是完全有效的,可以返回
true
false
,为什么要阻止它?

好吧,这是有意义的。。。
列表
将始终与
列表
不相交。为什么要出现类型错误?无论如何,这些类型都会在运行时被擦除。即使它们都包含
null
值?它是用通配符泛型为这两个参数定义的,这意味着它们可以是不同的类型。如果它被定义为具有公共类型的
addAll
方法,那么它将导致编译错误。@kajacx Oops没有考虑到这一点。但是编辑太晚了…为什么不应该认为这是一个错误?在我看来,这应该是一个编译错误。@BrendenBrown:为什么应该是一个编译错误?这种选择背后有一个确切的理由,因为在编译时阻止检查对象是否包含在集合中没有意义,即使它不是同一泛型类型。这与
删除(对象o)
之间的原理相同。没有有害的副作用。参数多态性是为了使代码安全,而不是限制开发人员。禁止使用不同类型的
contains
不会破坏类型安全性,这与实际键入的
add(E object)
不同。我认为这是无效的,因为程序员可能永远不需要这样做,结果总是一样的。我稍微更新了我的答案(代码中的注释)。你说程序员可能永远不需要这样做,这似乎是自以为是的?这些列表可能包含完全相同的实例,甚至可能不包含相同的类。通过在上述情况下尝试强制执行相同类型的集合,java将限制一个在其他方面有用、有效的场景。