Java 如何创建一个集合,其中只能添加一个不';不允许添加子类或超类?
我想要一个只包含一种数据类型的集合,不允许它的任何超类或子类被添加到集合中。好的,我想我完全误解了这一点 我可能会使用组合而不是继承,在内部委托给Java 如何创建一个集合,其中只能添加一个不';不允许添加子类或超类?,java,types,set,type-safety,Java,Types,Set,Type Safety,我想要一个只包含一种数据类型的集合,不允许它的任何超类或子类被添加到集合中。好的,我想我完全误解了这一点 我可能会使用组合而不是继承,在内部委托给HashSet,但在add中,您需要检查: if (o.getClass() != clazz) { // throw or reject } 请注意,这意味着您将在执行时需要实际的类,因此您需要使用以下内容构造集合: ExactTypeSet<String> x = new ExactTypeSet<String>
HashSet
,但在add
中,您需要检查:
if (o.getClass() != clazz)
{
// throw or reject
}
请注意,这意味着您将在执行时需要实际的类,因此您需要使用以下内容构造集合:
ExactTypeSet<String> x = new ExactTypeSet<String>(String.class);
ExactTypeSet x=新的ExactTypeSet(String.class);
您可以使用对象。getClass()确定对象的类型
如果您希望保证只添加MyClass类型的类,您可以扩展HashSet并重写add(Object o)
方法,并且仅在(o.getClass()==MyClass.class)
的情况下将元素添加到集合中
更新:添加了一个可以作为PoC运行的工作示例
public class MySet extends HashSet<MySet.MyClass> {
public static class MyClass {}
public static class MySubClass extends MyClass {}
@Override
public boolean add(MyClass c) {
if (c.getClass() != MyClass.class) {
throw new IllegalArgumentException("illegal class to add " + c.getClass().getName());
}
return super.add(c);
}
public static void main(String[] args) {
MySet set = new MySet();
set.add(new MyClass()); // works
set.add(new MySubClass()); // throws Exception
}
}
公共类MySet扩展HashSet{
公共静态类MyClass{}
公共静态类MySubClass扩展MyClass{}
@凌驾
公共布尔加法(MyClass c){
如果(c.getClass()!=MyClass.class){
抛出新的IllegalArgumentException(“要添加的非法类”+c.getClass().getName());
}
返回super.add(c);
}
公共静态void main(字符串[]args){
MySet set=新的MySet();
set.add(new MyClass());//有效
set.add(new MySubClass());//引发异常
}
}
运行此示例将产生:
线程“main”java.lang.IllegalArgumentException中的异常:
添加MySet$MySubClass的非法类
在非常特殊的情况下,如果您知道要添加的类的类型,您可以扩展现有的Set实现并重写add(Object o)
方法,只允许在o.getClass().getName().equals(“yourclassname”)的位置添加对象
我认为这不起作用,因为您不能覆盖add()
并同时更改其参数的类型。也许您的意思是add(objecte)
。这个示例很有效,您可以添加一个main方法,并使用HashSet
和getClass()=String.class
。我检查了。@Peter:add()的参数类型也是HashSet
->add(eo)
中的泛型类型E,所以HashSet
有add(MyClass o)
:你说得对,我在考虑像remove(Object)
和contains(Object)
这样的方法,检查实际的类会更简单。可以在不同的类加载器中使用相同的名称对两个类进行分类。(我倾向于让自己感到困惑并避免它;)不应该比较类名,而是直接比较类对象。在运行时可能有几个不同的类具有相同的名称(一个名称仅在单个类加载器加载的类集中是唯一的,但可能有几个类加载器)。