在java中使类不可变

时间:2012-03-19 03:08:02

标签: java object immutability

要使类不可变,我能做的是:

1)让课程结束 2)不提供制定者
3)将所有变量标记为最终

但是如果我的类有另一个类的其他对象,那么somone可以改变该对象的值

class MyClass{
 final int a;
 final OtherClass other 

 MyClass(int a ,OtherClass other){
  this.a = a;
  this.other = other;
 }

 int getA(){
   return a;
 }

 OtherClass getOther(){
   return other;
 }

 public static void main(String ags[]){
  MyClass m = new Myclass(1,new OtherClass);
  Other o = m.getOther();
  o.setSomething(xyz) ; //This is the problem ,How to prevent this?

}
}

7 个答案:

答案 0 :(得分:3)

A)使OtherClass也是不可变的

B)不允许直接访问OtherClass对象,而只提供getter充当代理。

编辑以添加:可以制作OtherClass的深层副本并返回副本而不是原始副本,但通常不是类型你期望在Java中的行为。

答案 1 :(得分:1)

我认为OtherClass(就像你说的其他一次)是一个你无法控制的类,或者必须有一个setter的类。

如果您无法删除getOther,请将其更改为getOtherView并返回other的只读视图。所有get方法都有包装器,但没有设置方法。

答案 2 :(得分:1)

从你的吸气剂中返回深层克隆。你可能会觉得这不是一件容易的事。

答案 3 :(得分:1)

不可变类中引用的所有对象都应该是不可变的,或者至少被封装为私有,并确保它们不被修改(不在类的方法内部,绝对不是从外部)。例如,如果您遇到这种情况:

public class MyImmutable {
    private MutableClass mutableObject;
}

...您无法提供getMutableObject()方法,因为这样做会为外部修改打开大门,如下所示:

myImmutable.getMutableObject().setSomeAttribute(newValue);

作为上述情况的一个特例,所有集合和/或映射都应该是不可变的,并使用ummodifiableXXX()类中的Collections方法。

答案 4 :(得分:1)

你不能(合理地)在java中停止它。如果你无法控制其他类,有办法有效地获得不可变行为,但在实践中它可能非常昂贵。基本上,您必须始终在任何公共方法返回值中返回该类的副本。 (jdk实际上有TimeZone类的这个问题)。

答案 5 :(得分:1)

  

但如果我的班级有另一个班级的另一个对象,那么,somone   可以改变那个对象的价值......

Java对象不是原始的。如果将基元标记为final,则分配后不能更改其值。但是,对象内容不能是最终的,只有对象引用才是最终的。所以你不能用这种方式制作一个物体。

一个解决方案可能是放弃所有setter / mutator方法,这些方法可以更改对象的特定字段并以只能访问它们的方式封装它们,而不是更改它们。

答案 6 :(得分:1)

可以通过以下方式在java中创建不可变类

1.不要提供制定者方法。

2.使所有字段都是最终字段和私密字段。

3.Make Class as final。