如何有效地实现可变对象的不可变和只读版本?

问题描述 投票:0回答:1

上下文:

  • 打包数据,公开:
public interface _Data {
   public String getData();
}
public class _PackageAPI {
    DataHolder holder;

    public void createHolder(String data) {
        holder = new DataHolder();
        holder.setData(data);
    }

    public void mutateHolder(String data) {
        holder.setData(data);
    }

    public _Data getSnapshot() {
        return DataSnapshot.from(holder.getData());
    }

    public _Data getReader() {
        return holder.readOnly();
    }
}
  • 包数据,包私有:
class DataHolder {
    private String data;

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public _Data readOnly() {
        return new _Data() {
            @Override
            public String getData() {
                return DataHolder.this.data;
            }
        };
    }
}
class DataSnapshot {
    public static _Data from(String data){
        return new _Data() {
            @Override
            public String getData() {
                return data;
            }
        };
    }
}
  • 示例客户端使用情况:
package clientPackage;

import data._Data;
import data._PackageAPI;

public class ExampleRunner {

    public static void main(String[] args) {

        _PackageAPI handler;

        System.out.println("Creating...");

        handler = new _PackageAPI();
        handler.createHolder("INITIAL DATA");

        System.out.println("Done creating...");

        _Data initialSnapShot =  handler.getSnapshot();
        _Data initialReader = handler.getReader();

        System.out.println("initialSnapShot holds :" + initialSnapShot.getData() );
        System.out.println("initialSnapShot class :" + initialSnapShot.getClass() );
        System.out.println("initialReader class :" + initialReader.getClass() );

        System.out.println("initialReader holds :" + initialReader.getData() );


        System.out.println("Mutating...");

        handler.mutateHolder("MUTATED DATA");
        _Data subsequentSnapShot =  handler.getSnapshot();
        _Data subsequentReader = handler.getReader();

        System.out.println("Done mutating...");


        System.out.println("initialSnapShot holds :" + initialSnapShot.getData() );
        System.out.println("initialReader holds :" + initialReader.getData() );

        System.out.println("subsequentSnapShot holds :" + subsequentSnapShot.getData() );
        System.out.println("subsequentReader holds :" + subsequentReader.getData() );



    }
}
  • 和控制台输出:
Creating...
Done creating...
initialSnapShot holds :INITIAL DATA
initialSnapShot class :class data.DataSnapshot$1
initialReader class :class data.DataHolder$1
initialReader holds :INITIAL DATA
Mutating...
Done mutating...
initialSnapShot holds :INITIAL DATA
initialReader holds :MUTATED DATA
subsequentSnapShot holds :MUTATED DATA
subsequentReader holds :MUTATED DATA
  • 第一个问题:给定getSnapshot()返回一个_Data(类:DataSnapshot $ 1),其方法getData()返回“实际”数据引用,即DataHolder对象的变量数据的内容, 这是安全的,还是可以利用对这个引用的访问来对DataHolder进行突变?如果是,怎么办?

  • 第一个简短问题:是否可以仅使用引用来对引用所引用的存储器的内容进行突变?

(当然,解决方案是克隆所引用的字符串。)

  • 第二个问题反正有没有要对DataSnapshot $ 1(_Data的“不可变”版本)实例进行更改?

    ] >>
  • 第三个问题

  • :给定DataHolder $ 1(_Data的“ readOnly”版本)在内部持有对提供该数据的DataHolder实例的引用,从DataHolder $ 1对象弄乱DataHolder实例吗?编辑:如果有的话,我会放一个偏执标签

[上下文:包数据,公共:公共接口_Data {public String getData(); }公共类_PackageAPI {DataHolder持有者;公共无效createHolder(字符串数据){持有人...

java immutability
1个回答
0
投票
这是安全的,还是可以利用此参考文献来对DataHolder进行突变?如果是,怎么办?
© www.soinside.com 2019 - 2024. All rights reserved.