限制Java中用于列表的类型

限制Java中用于列表的类型,java,generics,Java,Generics,如何传递一个带有一组未声明给方法的特定允许类型的列表 例如,将类型限制为整数、布尔值和字符串: // Pseudo code public void method(List<Integer OR Boolean OR String> myList); 如果我是声明这些子类(AllowedTypeA extensed Parent)的人,那就足够了。但是,如果我不是想要使用的类的所有者(我不能使Integer扩展Parent),我该怎么办?最好的办法是将这个混合列表包装到一个类中,并

如何传递一个带有一组未声明给方法的特定允许类型的
列表

例如,将类型限制为整数、布尔值和
字符串

// Pseudo code
public void method(List<Integer OR Boolean OR String> myList);

如果我是声明这些子类(
AllowedTypeA extensed Parent
)的人,那就足够了。但是,如果我不是想要使用的类的所有者(我不能使
Integer
扩展
Parent
),我该怎么办?

最好的办法是将这个混合列表包装到一个类中,并提供方法来添加您希望允许的内容:

class WrappedMix {
    private List<Object> oddsAndEnds = ...

    public void add( Integer el ){ oddsAndEnds.add( el ); }
    public void add( Boolean el ){ oddsAndEnds.add( el ); }
    public void add( String el ){ oddsAndEnds.add( el ); }
}
类WrappedMix{
私有列表oddsands=。。。
public void add(整数el){oddsands.add(el);}
公共void add(布尔el){oddsands.add(el);}
public void add(String el){oddsands.add(el);}
}
或使用适当的重写(和重载)扩展ArrayList


尽管我很好奇为什么你会想要这样一个列表——它的处理并不方便。

从概念上讲,我更喜欢@laune的解决方案。我更喜欢类型安全和编译错误,而不是任性地将一堆东西扔进列表,忘记添加允许的类型

也就是说,这仍然是可能的,尽管您必须做一些额外的工作来实现这一点,也就是说,如果您删除了对象类型,您可能还应该删除与它相关的所有对象,并且需要覆盖其他方法,例如
addAll
,以确保正确的功能

与laune的方法相比,这种方法更加灵活,因为您可以随时添加许可类型。就你的情况而言,可能不是最好的,但一般的问题仍然很有趣,所以我试了一下。也许您希望某些列表存储整数,但不希望其他列表存储整数。可以使用
addPermittedObject
方法执行此操作

public class SelectiveList extends ArrayList<Object> {
    //the (types of) objects that we can store
    private ArrayList<Object> permittedObjects = new ArrayList<Object>();

    // put an Object type into the list
    public boolean addPermittedObject(Object o) {
        for (Object type : permittedObjects) {
            if (type.getClass() == o.getClass()) {
                return false; // if we already have it, do not add it again
            }
        }
        return permittedObjects.add(o); // else let's add it
    }

    // remove the Object type
    public boolean removePermittedObject(Object o) {
        for (Object type : permittedObjects) {
            if (type.getClass() == o.getClass()) {
                return permittedObjects.remove(type);
            }
        }
        return false;
    }

    @Override
    public boolean add(Object o) {
        for (Object type : permittedObjects) {
            if (type.getClass() == o.getClass()) {
                return super.add(o); // go ahead and add the item since it
                                        // matches our list
            }
        }
        return false;
    }
}

不能在Java中表示“或”类型约束。你能解释一下你试图实现的方法需要那种约束吗?泛型可能是错误的解决方案。它们应该是“通用的”,因此得名。如果您只能支持某些类型(或具有特定于该类型的逻辑),则可能应该为每个特定类型提供重载方法。@mellamokb虽然在这种情况下重载不起作用,但所有
列表
参数都将擦除为
列表
,因此除非有其他参数,否则会发生冲突(或者以不同的方式命名,在这种情况下它不是重载)@LouisWasserman该列表将被序列化为一个平面JSON对象,没有数组或对象作为属性。只有
Integer
s、
Boolean
s和
String
s。听起来你应该创建一个包含整数、布尔和字符串数据的子类的“FlatObject”类,并且有一个列表。几乎完美,thx!这不是虽然是一个
列表
。但是这个想法是适用的:如果给定对象不是
add()中的
整数
布尔
字符串
的实例,则实现一个
列表
,并抛出一个
非法argumentexception
方法。如果您愿意,可以创建一个扩展
列表的自定义类,这样您就可以拥有一个
CustomList
并更轻松地处理
实例。通常,需要决定是采用(可能更严格但更安全的)类型安全方法还是非常灵活的(甚至是运行时可配置的!)最好的方法是将类保存在
列表中
class WrappedMix {
    private List<Object> oddsAndEnds = ...

    public void add( Integer el ){ oddsAndEnds.add( el ); }
    public void add( Boolean el ){ oddsAndEnds.add( el ); }
    public void add( String el ){ oddsAndEnds.add( el ); }
}
public class SelectiveList extends ArrayList<Object> {
    //the (types of) objects that we can store
    private ArrayList<Object> permittedObjects = new ArrayList<Object>();

    // put an Object type into the list
    public boolean addPermittedObject(Object o) {
        for (Object type : permittedObjects) {
            if (type.getClass() == o.getClass()) {
                return false; // if we already have it, do not add it again
            }
        }
        return permittedObjects.add(o); // else let's add it
    }

    // remove the Object type
    public boolean removePermittedObject(Object o) {
        for (Object type : permittedObjects) {
            if (type.getClass() == o.getClass()) {
                return permittedObjects.remove(type);
            }
        }
        return false;
    }

    @Override
    public boolean add(Object o) {
        for (Object type : permittedObjects) {
            if (type.getClass() == o.getClass()) {
                return super.add(o); // go ahead and add the item since it
                                        // matches our list
            }
        }
        return false;
    }
}
public static void main(String[] args) {
    SelectiveList selectiveList = new SelectiveList();
    selectiveList.add("Potato");
    selectiveList.add(1);
    selectiveList.add(true);
    System.out.println(selectiveList.size()); // prints 0
    // these objects need to be initialized, but their contents do not
    // matter
    selectiveList.addPermittedObject(new String());
    selectiveList.addPermittedObject(new Boolean(false));
    selectiveList.addPermittedObject(new Integer(1));
    selectiveList.add("Potato");
    selectiveList.add(1);
    selectiveList.add(true);
    System.out.println(selectiveList.size()); // prints 3
}