Java 该对象内部对象的Arraylist

Java 该对象内部对象的Arraylist,java,android,Java,Android,假设我使用的代码如下所示: public class MyObject { private int id; private ArrayList<MyObject> otherObjects; public MyObject(int id) { this.id = id; ArrayList<MyObject> otherObjects = new ArrayList<MyObject>();

假设我使用的代码如下所示:

public class MyObject {
    private int id;
    private ArrayList<MyObject> otherObjects;

    public MyObject(int id) {
        this.id = id;
        ArrayList<MyObject> otherObjects = new ArrayList<MyObject>();
        otherObjects.add(new MyObject(id + 1));
        this.otherObjects = otherObjects;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public ArrayList<MyObject> getOtherObjects() {
        return otherObjects;
    }

    public void setOtherObjects(ArrayList<MyObject> otherObjects) {
        this.otherObjects = otherObjects;
    }
}

我应该注意哪些陷阱?我的另一个担忧是,如果我能将这个类打包?

如果你用不同的线程运行它,你就有数据竞争,因为你没有全局变量的锁。

如果你用不同的线程运行它,你就有数据竞争,因为你没有全局变量的锁。

补充Mathew Palsberg所说的

ArrayList是不同步的,因此它们不是线程安全的

请注意,此实现是不同步的。如果有多个线程 并发访问ArrayList实例,并至少访问 线程从结构上修改列表,它必须同步 外部。结构修改是指添加或修改 删除一个或多个元素,或显式调整支持数组的大小; 仅仅设置一个元素的值并不是一个结构性的问题 修改这通常是通过在某些服务器上进行同步来实现的 对象,该对象自然地封装了列表。如果不存在这样的物体, 应使用Collections.synchronizedList包装列表 方法最好在创建时执行此操作,以防止意外事件 对列表的非同步访问:

List List=Collections.synchronizedListnew ArrayList

资料来源:

补充马修·帕斯伯格的话

ArrayList是不同步的,因此它们不是线程安全的

请注意,此实现是不同步的。如果有多个线程 并发访问ArrayList实例,并至少访问 线程从结构上修改列表,它必须同步 外部。结构修改是指添加或修改 删除一个或多个元素,或显式调整支持数组的大小; 仅仅设置一个元素的值并不是一个结构性的问题 修改这通常是通过在某些服务器上进行同步来实现的 对象,该对象自然地封装了列表。如果不存在这样的物体, 应使用Collections.synchronizedList包装列表 方法最好在创建时执行此操作,以防止意外事件 对列表的非同步访问:

List List=Collections.synchronizedListnew ArrayList


资料来源:

您担心什么?实际上,有一种非常常见的设计模式使用了这种方法:看起来像是无限递归,您将其称为“newmyobject;”在构造函数内部。@markspace不,它不会是无限递归,因为将发生构造函数重载,因此,甚至没有递归的机会@这是一个构造函数,不是一个方法。此外,它使用相同的签名。因此,它肯定会遇到堆栈溢出。只要把它放到ideone中,你就会看到。构造函数,但不是int参数,如果我错了,请纠正我@英戈尔。OP将在代码中声明一个新的构造函数来处理没有参数的对象实例化。我猜markspace的逻辑是错误的!你担心什么?实际上,有一种非常常见的设计模式使用了这种方法:看起来像是无限递归,您将其称为“newmyobject;”在构造函数内部。@markspace不,它不会是无限递归,因为将发生构造函数重载,因此,甚至没有递归的机会@这是一个构造函数,不是一个方法。此外,它使用相同的签名。因此,它肯定会遇到堆栈溢出。只要把它放到ideone中,你就会看到。构造函数,但不是int参数,如果我错了,请纠正我@英戈尔。OP将在代码中声明一个新的构造函数来处理没有参数的对象实例化。我猜markspace的逻辑是错误的!