如何在java中的arrylist上执行深层复制

时间:2017-01-12 07:06:41

标签: java

我有一个成员变量

private ArrayList<CalendarableItem>[] resourceColumns = null;

和getter相同的

 public ArrayList<CalendarableItem>[] getResourceColumns()
{
    return resourceColumns;
}

我看到上面的getter方法的findbugs。 恶意代码漏洞:EI:返回数组的方法可能会暴露内部表示

我发现我必须对数组对象进行深层复制才能删除此错误Malicious code vulnerability - May expose internal representation by incorporating reference to mutable object

由于性能问题,我不想克隆此对象。我们还有其他更好的解决方案。

2 个答案:

答案 0 :(得分:0)

如果希望List在深度上不可变,请删除getter。该getter返回列表可以删除,添加......其中的任何项目。

您可以使用类似于适配器的东西来提供您想要的访问权限。像特定的getter或列表的大小,但没有访问列表。

private List<CalendarableItem> resourceColumns = new ArrayList<>();

public CalendarableItem getCalendarableItem(int index){
     return resourceColumns.get(index);
}

public int getSize(){ return resourceColumns.size(); }

您的列表将是不可变的(目前)。唯一可能的访问是您在课堂上适应的那些。

如果要阻止实例更新,您也可以返回它的副本,因为目前,实例返回是列表中的实例(相同的引用)。

编辑:我刚刚注意到这是一个ArrayList数组,所以这个例子不是像这样的函数,它是为一个简单的ArrayList编写的。您需要根据需要更新适配器。

答案 1 :(得分:0)

只是建议而不是使用ArrayList<CalendarableItem>[],您应该use List<List<CalendarableItem>>

现在回到你的问题,你可以返回数组的克隆,这样如果任何一个对数组进行任何更改,它将不会反映在你的初始数组中。

public ArrayList<CalendarableItem>[] getResourceColumns()
{
    return Arrays.copyOf(resourceColumns, resourceColumns.length);
}

如果你想要/需要更多控制,而不是方法getResourceColumns(),你需要在特定的数组索引等处编写单独的方法返回对象。