[英]Restrict mutable object inside immutable object Java
我正在学习不可变的对象。 我正在尝试这段代码
public final class ImmutableObject {
private final String name;
private final NormalObject obj = new NormalObject();
public String getName() {
return name;
}
public ImmutableObject(String name) {
this.name = name;
obj.setName(name);
}
public NormalObject getObj() {
NormalObject tempObj = obj;
return tempObj;
}
}
public class NormalObject {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
我想限制调用类更改NormalObject的name变量的值
但是以下代码更改了值
ImmutableObject obj = new ImmutableObject("Siddle");
System.out.println(obj.getObj().getName()); //prints Siddle
obj.getObj().setName("Kelly");
System.out.println(obj.getObj().getName()); //prints Kelly
如何限制它?
对于不可变的对象,其所有属性必须是不可变的。 它的状态一定不可改变。
要做到这一点,你必须在NormalObject
上放置一个不可变的Facade,你不能直接返回一个NormalObject
。 返回它的方法也需要一个不同的返回类型,你不能返回NormalObject
但实际上返回的行为不像NormalObject
。
例如:
public final class ImmutableObject {
private final String name;
private final NormalObject obj = new NormalObject();
private final ImmutableNormalObject objFacade = new ImmutableNormalObject(obj);
public String getName() {
return name;
}
public ImmutableObject(String name) {
this.name = name;
obj.setName(name);
}
public ImmutableNormalObject getObj() {
return objFacade;
}
}
public class NormalObject {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class ImmutableNormalObject {
private NormalObject obj;
public ImmutableNormalObject(Normalobject o) {
this.obj = o;
}
public String getName() {
return obj.getName();
}
}
或者,如果复制对象并且它有一个复制构造函数(或者你可以添加一个)是可以接受的,那么你可以这样做,但复制和返回是很昂贵的。
您可以通过在getter中返回normalObject
的副本来完成此操作:
public NormalObject getObj() {
return new NormalObject(obj.getName());
// or you can make a copy constructor:
// return new NormalObject(obj);
}
或者您可以为NormalObject
创建一个忽略名称设置器的包装器,但它会制动逻辑。
请将您的NormalObject代码更改为
public final class ImmutableObject {
private final String name;
// initialise it to null
private final NormalObject obj = null;
public String getName() {
return name;
}
public ImmutableObject(String name) {
this.name = name;
// use the Constructor for setting name only once during initialization of ImmutableObject via its constructor
obj = new NormalObject(name);
//obj.setName(name);
}
public NormalObject getObj() {
NormalObject tempObj = obj;
return tempObj;
}
}
NormalObject类
public class NormalObject {
private String name;
public NormalObject(name){
this.name = name;
}
public String getName() {
return name;
}
//Remove any setter on NormalObject
/*public void setName(String name) {
this.name = name;
}*/
}
在不可变对象中,如果用户尝试更改Object的状态。 要么你不允许或返回一个新的Immutable类实例。
所以,因为Date是一个可变类。 您可以在日期周围创建一个不可变的包装器,并且您只能公开那些可以在Immutable-Date的透视图中使用的方法,但是您返回一个新的Immutable类实例,其中包含新Date的已更改属性。
我不认为Immutable变量需要final,因为它已经是private和Immutable。
示例:
public class Main{
private ImmutableDate immutableDate;
public Main() {
this.immutableDate = new ImmutableDate(new Date());
}
public Main(Date date){
this.immutableDate = new ImmutableDate(date);
}
public ImmutableDate getDate() {
return immutableDate;
}
public class ImmutableDate{
// private constructor, so this can only be instantiated within the outer class
// therefore, final keyword not required for Date, as no access given to the variable
private Date date;
private ImmutableDate(Date date) {
this.date = date;
}
// Example methods from Date, that are required for our Immutable implementation
public Main setTime(long time){
Date date1 = new Date();
date1.setTime(time);
return new Main(date1);
}
@Override
public String toString() {
return date.toString();
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.