TreeSet不能在编译时检查比较器对象吗?

时间:2019-05-04 09:54:47

标签: java class oop interface

在使用默认构造函数(无参数)在Java中创建TreeSet类的实例,并添加两个未实现Comparator接口的类的对象时,该对象将引发运行时异常。可以在编译时执行此检查吗?

我尝试了以下代码:

Dummy.java

public class Dummy {
}

TreeSetTest.java

import java.util.TreeSet;

public class TreeSetTest {

    public static void main(String[] argv) {
        TreeSet<Dummy> treeSet = new TreeSet<>();
        treeSet.add(new Dummy());
        treeSet.add(new Dummy());
    }
}

编译器在创建TreeSet时会抱怨,因为它没有实现Comparable。

3 个答案:

答案 0 :(得分:1)

如果addIncomeButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { //TODO: Transfer this info to line in scroll view showing incomes if (TextUtils.isEmpty(enterIncomeEditText.getText()) | TextUtils.isEmpty(enterIncomeNamesEditText.getText())) { Toast.makeText(Income.this, "Entry Empty", Toast.LENGTH_SHORT).show(); } else { //create income and incomeName strings income = enterIncomeEditText.getText().toString(); incomeName = enterIncomeNamesEditText.getText().toString(); mLayout.addView( createNewTextView(incomeName + " " + income)); } } }); 构造函数不是公共的,则可以在编译时使用如下所示的工厂方法进行检查:

TreeSet()

您只能使用自然可比的类型参数来调用它:

public static <E extends Comparable<? super E>> TreeSet<E> create() {
  return new TreeSet<>();
}

但是构造函数是公共的;而且Java中没有语言机制允许您限制用于调用构造函数的类型参数。

此构造函数必须是公共的,因为它早于泛型之前就已经存在,因此删除它会违反向后兼容性。

答案 1 :(得分:-1)

您可以编写自己的函数,以便需要实现Comparable进行编译:

static <E extends Comparable> boolean addWithCheck(TreeSet<E> treeSet, E e) {
    return treeSet.add(e);
}

然后这样称呼它:

TreeSet<Dummy> treeSet = new TreeSet<>();
addWithCheck(treeSet, new Dummy());

答案 2 :(得分:-1)

不,编译器不应对此抱怨。

让我们假设您还有一个Dummy子类,它实现了Comparable

public class NotSoDummy extends Dummy implements Comparable {
    @Override
    public int compareTo(Object o) {
        ...
    }
}

该类的实例应该没有问题地添加到TreeSet中。编译器无法检查所有代码(实际的,将来的)以检查是否存在最终可以添加到Dummy的{​​{1}}扩展名。