Search code examples
javamodelprivategetter-setter

Accessing private variable of Model class without getters


I have a Model class defined in my project. and as usual it has some private variables and public getters and setters

public class Person{

 private ArrayList<String> mark;

 public void setMark(ArrayList<String> mark){
  this.mark = mark;
 }

 public void getMark(){
  return this.mark;
 }
}

Suppose in some other class I am using this Model like

Person person = new Person();
ArrayList<String> mark = new ArrayList();
mark.add("10");
mark.add("15");
mark.add("18");
person.setMark();

then the private variable of person holds the value "my name", the I am accessing the variable using public getter of the class like

ArrayList<String> localMark = person.getMark()

so as per my knowledge person.getMark() returns the reference of private variable name, so if I modify the local variable 'localMark', then it will effect the private variable of Person class, so there it breaks the private property of the variable

ex:

 ArrayList<String> localMark = person.getMark();
 System.out.println(localMark.get(0)); // will be "10"
 localMark.set(0,"25") // person.mark will be changed
 System.out.println(person.getMark().get(0)); //will be printing "25"

most of the developers following the same design pattern I guess, but what is the correct way to create Models

EDIT

As per the comment of vinod I checked, and Strings it passes value but not reference but for ArrayList... it returns reference.


Solution

  • If the instance being exposed by call to get() is mutable, then whatever changes you make in some other place will be reflected in the instance everywhere it is used.

    Example :

    methodX classA - 
     List<String> locaNamesList = person.getNamesList();
     locaNamesList.clear();
    
    Somewhere else
    methodY classB -
    List<String> locaNamesList = person.getNamesList(); // note the same person instance should be used.
    //locaNamesList will be empty here
    

    Just re-assigning the reference won' change anything.

    List<String> locaNamesList = person.getNamesList();
    locaNamesList = null; // won't change the actual list. You are setting local field locaNamesList to null and not the actual instance.
    

    You have to use defensive-copies of mutable instances and pass them around if you don't want the original instance to be changed by external players (provided you can't make the instance itself immutable)