Is it possible to make an object “Read Only” to a method

后端 未结 11 1911
攒了一身酷
攒了一身酷 2020-12-29 06:33

If an object reference is passed to a method, is it possible to make the object \"Read Only\" to the method?

11条回答
  •  独厮守ぢ
    2020-12-29 06:51

    I believe your real question is about avoiding escape references.

    As pointed out in some answers to extract an Interface from class and expose only get methods. It will prevent modification by accident but it is again not a foolproof solution to avoid above problem.

    Consider below example:

    Customer.java:

    public class Customer implements CustomerReadOnly {
    
        private String name;
        private ArrayList list;
    
        public Customer(String name) {
            this.name=name;
            this.list = new ArrayList<>();
            this.list.add("First");
            this.list.add("Second");
        }
    
        @Override
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public ArrayList getList() {
            return list;
        }
        public void setList(ArrayList list) {
            this.list = list;
        }
    
    }
    

    CustomerReadOnly.java:

    public interface CustomerReadOnly {
    
        String getName();
    
        ArrayList getList();
    
    }
    

    Main.java:

    public class Test {
        public static void main(String[] args) {
            CustomerReadOnly c1 = new Customer("John");
    
            System.out.println("printing list of class before modification");
            for(String s : c1.getList()) {
                System.out.println(s);
            }
    
            ArrayList list = c1.getList();
            list.set(0, "Not first");
    
            System.out.println("printing list created here");
            for(String s : list) {
                System.out.println(s);
            }
    
            System.out.println("printing list of class after modification");
            for(String s : c1.getList()) {
                System.out.println(s);
            }
        }
    }
    

    Ouput:

    printing list of class before modification
    First
    Second
    printing list created here
    Not first
    Second
    printing list of class after modification
    Not first
    Second
    

    So, as you can see extracting interface and exposing only get methods works only if you don't have any mutable member variable.

    If you have a collection as a member variable whose reference you don't want to get escape from class, you can use Collections.unmodifiableList() as pointed out in ewernli's answer.

    With this no external code can modify the underlying collection and your data is fully read only.

    But again when it comes to custom objects for doing the same, I am aware of the Interface method only as well which can prevent modification by accident but not sure about the foolproof way to avoid reference escape.

提交回复
热议问题