Java 6 Collections.checkedList适当的用法

时间:2011-10-20 17:04:39

标签: java inheritance

我正在创建几个函数,我想在其中返回接口而不是实现,I.E。列表而不是ArrayList。我的方法签名和简要实现如下:

public List<MyAwesomeComposedObject> convert(Collection<MyAwesomeObject> awesomeObjects>)
{
    List<MyAwesomeComposedObject> composedObjects = new ArrayList<MyAwesomeComposedObject>();
    for(MyAwesomeObject awesomeObject : awesomeObjects)
    {
        MyAwesomeComposedObject composedObject = new MyAwesomeComposedObject(awesomeObject);
        composedObjects.add(composedObject);
    }

    List<MyAwesomeComposedObject> composedObjectList = Collections.checkedList<composedObjects, MyAwesomeComposedObject.class);
    return composedObjectList;
}

我的问题是,这是某种反模式吗?我想保证这个方法的调用者获取接口而不是实现。我也不认为这是过度工程的情况。如果这不是返回接口的正确方法,那么在这种情况下,我可以接受正确的实现。

附件是一个导致异常的小程序:

public static void main(String[] args)
{
    Vector v = (Vector) c();
}

static List<Object> c()
{
    List<Object> l = new ArrayList<Object>();
    l.add(new Object());
    List<Object> o = Collections.checkedList(l, Object.class);
    return o;
}

javadoc在这里:checked list

3 个答案:

答案 0 :(得分:2)

返回的List是Collections.CheckedList而不是Vector。你不能引用对象不是的类型。

然而,你可以做的是

public static void main(String[] args) {
    Vector<Object> v = new Vector<Object>(c());
}

composedObjects已经是一个List,你可以返回它。

public List<MyAwesomeComposedObject> convert(Collection<MyAwesomeObject> awesomeObjects>)  {  
   List<MyAwesomeComposedObject> composedObjects = new ArrayList<MyAwesomeComposedObject>();  
   for(MyAwesomeObject awesomeObject : awesomeObjects)    
        composedObjects.add(new MyAwesomeComposedObject(awesomeObject));  
   return composedObjects;
}

答案 1 :(得分:1)

对于您修改过的问题:无法阻止调用者尝试强制转换为他们想要的任何内容。如果是不合适的演员,他们将获得例外。这就是为什么强烈建议不要从接口到具体类的强制转换的原因。

如果您真的对此感到担心,请考虑返回ArrayList而不是List。这应该阻止铸造,因为他们正在得到一个具体的类型。请注意,我不认可这一点,这只是一个选择。

  

我想保证此方法的调用者获取接口而不是实现

这是无效的。您返回List,其中元素的声明类型是接口,但每个元素必须是SOME实例化。所有已检查的集合都会阻止添加不正确类型的元素。没有什么可以阻止用户回退到实现类型。

如果您尝试确保用户获得List而不是ArrayList(我的假设是因为我没有看到您的Awesome类的界面),这又是有缺陷的,因为用户仍然可以将List转换为ArrayList,但这可能是一个坏主意,因为它会冒ClassCastException的风险。

答案 2 :(得分:0)

不,我建议尽可能简化代码。阅读Javadoc以了解何时使用Collections.checkedList

的讨论

http://download.oracle.com/javase/7/docs/api/java/util/Collections.html#checkedCollection%28java.util.Collection,%20java.lang.Class%29