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

后端 未结 11 1853
攒了一身酷
攒了一身酷 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:45

    You could define all parameters of the objects as final but that makes the object read only to everyone.

    0 讨论(0)
  • 2020-12-29 06:46
    private boolean isExecuteWriteQueue = false;
    public boolean isWriting(){
        final boolean b = isExecuteWriteQueue;
        return b;
    }
    
    0 讨论(0)
  • 2020-12-29 06:51

    No. But you could try to clone the object before passing it, so any changes made by the method won't affect the original object.

    0 讨论(0)
  • 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<String> 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<String> getList() {
            return list;
        }
        public void setList(ArrayList<String> list) {
            this.list = list;
        }
    
    }
    

    CustomerReadOnly.java:

    public interface CustomerReadOnly {
    
        String getName();
    
        ArrayList<String> 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<String> 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.

    0 讨论(0)
  • 2020-12-29 06:54

    making it implement a interface which has only read only methods (no setter methods) this gives a copy of an object (road-only copy) and returning the read only instance of interface instead of returning the instance of an object itself

    0 讨论(0)
提交回复
热议问题