如何允许两种类型的数据作为参数

时间:2011-02-21 11:04:20

标签: java generics

private void setSomething(final List<?> someListOfObjects){

}

修改

抱歉,我觉得我很困惑别人 -

我希望列表只包含Double和/或自定义对象(用户定义的类)。它可以是两者的混合。我怎么保证呢?


使用更多详细信息进行编辑:

我们使用Apache POI为不同的客户端程序生成简单的Excel文件。我正在为此写一个模板。要创建行,用户可以将一个双精度列表作为行的单元格值传递,程序将使用该单元格的默认样式(CellStyle)。此外,用户可以传递可以由双精度和一种自定义对象组成的列表。自定义对象是一个类,其中定义了单元格值和该单元格的样式。所以,当我创建一行时,我得到列表的值。如果值是double,我为该单元格应用默认单元格样式,但如果该值是自定义对象,则应用给定样式。

8 个答案:

答案 0 :(得分:2)

  

我希望列表只包含Double   和/或自定义对象(用户定义的   类)。它可以是两者的混合。   我如何保证?

这是不可能的,这是糟糕的设计,因为它打破了类型安全 - 你无法知道列表在给定索引中包含的类型。

我们必须更多地了解您实际上想要做什么才能说出最佳设计解决方案。

修改 您不应该在列表中混合使用原始值和样式化值(“自定义对象”),而应该只允许使用同类列表以及使用默认样式生成“自定义对象”的便捷方法。

答案 1 :(得分:1)

创建另一个包装Double和/或CustomObject的类,并将其用作列表类型。

public class Container {
    private Double d;
    private CustomObject customObject;

    // ...
}

private void setSomething(List<Container> containers) {
    // ...
}

答案 2 :(得分:0)

尝试List<Number>,这将允许所有包装类。

答案 3 :(得分:0)

我认为不可能,你必须定义两种方法。

或者,您可以使用:

private  <T extends Number> void  setSomething(final List<T> someListOfObjects)

答案 4 :(得分:0)

“双重和/或自定义对象”与众不同! 的工作原理如下:

private <T extends Double & CustomObject> void setSomething(final List<T> someListOfObjects)

但实际类型检查无法使用

编辑(在给出更多细节之后):

两种vararg方法怎么样?

private void setSomething(final Double... someListOfObjects)
private void setSomething(final CustomObject... someListOfObjects)

答案 5 :(得分:0)

  

我希望列表只包含Double和/或自定义对象

由于没有泛型or,列表将具有泛型类型的Object,使得编译时检查变得不可能,即使有类似的东西,也不能在没有强制转换的情况下使用对象(丑陋的代码)。

您可以将列表拆分为两个以进行编译时检查。

private void setSomething(List<Double> listDoubles, List<MyClass> listOther);

或者您必须在运行时使用instanceOf

private void setSomething(List<?> listObj){
   for(Object o:listObject){
       if(!(o instanceof Double))
         if(!(o instanceof MyClass))
             throw  new IllegalArgumentException();
   }

}

答案 6 :(得分:0)

您可以创建一个允许混合对象的自己的List类型,而不是通常的List类型(这里不可用)。这是一个接口的想法:

public interface MixedList {

    public int size();

    /**
     * returns an element of the list, if it has the right type.
     * @return null if the element is not of the right type, otherwise
     *    the element.
     */
    <T> public T get(int index, Class<T> type);

    /**
     * returns the type of an element.
     */
    public Class<?> getType(int index);

    /**
     * adds a typed element to the end of the collection
     */
    <T> public void add(Class<T> type, T element);

    /**
     * replaces an element of the collection.
     */
    <T> public void set(int index Class<T> type, T element)
}

但正如其他回答者已经说过的那样,这将是一个痛苦的计划,因为你总是要检查类型。也许更好的解决方案是不存储Double和CustomClass的元素,而只存储CustomClass,并提供一个简单的函数,如

  public CustomClass wrapNumber(double d)

创建未格式化的单元格。

或者简单地使用无类型集合(List或类似)并查找每个对象,无论它是否是受支持的类型之一。 (为了生成Spreadsheets,我认为通常文本字符串也很有用。)

答案 7 :(得分:-1)

<强>编辑: 因为内容是混合的:

private void setSomething(final List someListOfObjects)
{
   for(Object n : someListOfObjects){
     if(n instanceof Double) {}
     else if(n instanceof Long) {}
     ...
   }
}