Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果一个类的实例变量为java.lang.Object,如何使其不可变?_Java_Immutability - Fatal编程技术网

如果一个类的实例变量为java.lang.Object,如何使其不可变?

如果一个类的实例变量为java.lang.Object,如何使其不可变?,java,immutability,Java,Immutability,这是不正确的。将成员变量设为private final并复制参数: o/p : Mon Aug 22 00:50:04 IST 2011 这将不允许任何其他类更改您的内部状态,也不允许ImmutableWithobject更改myList或obj引用。然而,obj的状态以及列表仍然可以在内部操纵。正如其他人所指出的,无论谁通过了列表或obj1,都可以从外部操纵它。由于C++中没有等价于“代码> const 的东西,所以我们必须复制对象以确保它们不从外部改变。 类似地,如果有getter,它也应

这是不正确的。

将成员变量设为private final并复制参数:

o/p : Mon Aug 22 00:50:04 IST 2011
这将不允许任何其他类更改您的内部状态,也不允许ImmutableWithobject更改
myList
obj
引用。然而,obj的状态以及列表仍然可以在内部操纵。正如其他人所指出的,无论谁通过了列表或obj1,都可以从外部操纵它。由于C++中没有等价于“代码> const <代码>的东西,所以我们必须复制对象以确保它们不从外部改变。 类似地,如果有getter,它也应该只返回一个副本(或某个只读接口或只读包装):


可以复制列表对象的值。调用它的人仍然拥有该列表并可以修改它。

不可变意味着一旦构建了对象,其状态就不会改变

  • 使课程成为最终课程(您已经完成)
  • 将实例变量设置为private和final
  • 不要提供更改状态的方法
  • 传递实例变量时,发送副本而不是原始副本

从EJ Item 15中,您不能使其不可变,因为此对象无法创建列表或对象内容的副本。假设您打算使用getter来访问这些属性,那么这些属性本身是在其他地方创建的,可以在该类外部的代码中更改,该类引用了这些属性


唯一的例外是对象和列表的内容本身是不可变的。然后,您可以创建列表的不可变副本,您就可以完成了。

但是,这并不会使
列表
不可变。问题的第一件事是,当这个对象在那个时候被实例化时,您可以使用java.util.Date作为对象。这不会在易变性方面给定义的类添加任何内容,因为无论如何都无法更改这些属性。无法使
列表
实例无论如何都是不可变的(
obj
note)。但是,我更改了访问修饰符,因此至少它不能在外部更改,并且接口可以确保不可变。@罗宾:好的,我知道原始海报现在可能在寻找什么。您打算在创建后公开对象吗?(例如,一个getObj()方法?)请详细说明您的问题,以便明确您真正想要防止的是什么(内部状态保护、信息隐藏、封装)。我已经发布了全部代码。现在的问题是让这个类不可变,而应该应用常识。如果这个类是final,那么private和final不会有什么区别(只要它们不是公共的)。要使其不可变,您只需接受不可变类作为构造函数的参数,或将它们复制到构造函数中。如果传入可变类,则无法保证不变性。@Robin——如果字段受保护或包私有,则同一包中的其他类可以获取对它的引用并对其进行修改。将它们标记为final也是必要的,因为否则在线程之间传递对象而不同步时可能会遇到问题。Robin您是对的,但应该有一些通用的方法来复制对象类型。@Robin,不是真的。如果私有字段将由多个线程使用,那么必须使用某种并发可见性机制。使字段为final允许所有线程看到相同的状态。其他选择包括同步和易失性。
o/p : Mon Aug 22 00:50:04 IST 2011
final class ImmutableWithObject {

    private final Object obj;
    private final List myList;

    public ImmutableWithObject(Object obj1 , List list)
    {
       this.obj = obj1.clone();
       this.list = (List) list.clone();
    }
}
 public Object getObj() { return obj.clone(); }