15

It is always recommended to use getter/setter for accessing private variables. Why would it not be a better idea to declare them as public and access them. Anyway we are accessing it using getter and setter?

user
  • 5,335
  • 7
  • 47
  • 63
nikhil
  • 9,023
  • 22
  • 55
  • 81

7 Answers7

19

Encapsulation.

Hiding internal state and requiring all interaction to be performed through an object's methods is known as data encapsulation — a fundamental principle of object-oriented programming.

See also:

mre
  • 43,520
  • 33
  • 120
  • 170
  • +1 exactly. And maybe later do caching. – Amir Raminfar Aug 26 '11 at 16:54
  • For the trivial and frequent case of having a private primitive or String or File and then a public Getter/Setter pair with the setter taking an argument of the input type to just set the value I fail to see how there is encapsulation. You're exposing a typed promise to change the state of the member; you could just as well expose the typed member itself. I think the only situation where this encapsulation by Getter/Setter adds value is when you have code written against the API that you don't control yourself. Then, yes, use Getter/Setter to encapsulate; otherwise, keep it simple. – Lumi Nov 05 '11 at 16:47
12

@mre answer is excellent and your question is fundamental. To summarize : you put the fields of an object private to gain control over the way it will be used by other objects. Your object uses setter to:

  • restrict and validate data passed to the setter
  • hide its inner data structure (other object are interested by a service not how the service is built, this can also include optimisation)
  • preserve its integrity in every state (changing other fields if required)

it will use getter to

  • format data in output as desired by the client
  • control a sequence of services (for instance it will provide data if and only if a connection has been established)

welcome in the wonderfull world of OO programming and the magics of structured programming.

Stéphane

Snicolas
  • 37,840
  • 15
  • 114
  • 173
  • 2
    so if you made the fields private and has setters/getters for them, aren't you still exposing the fields to things outside of the class? The fields could be modified through the setters and getters as well...so why does making it private and having setters/getters better and protect this? – Glide Oct 26 '11 at 02:21
  • There is no obligation of any relationship between your params in the setters and your internal data structure. You could have a setter requiring a string and store an int. The point is that you can validate the new values before storing them in your fields. With getters people could, and u right, get a reference on one of your fielsd and change it later. If you fear this, again, there is no need to return your real field, this could be a copy or an immutable view of your fields. – Snicolas Nov 15 '11 at 12:35
11

All of the answers above are excellent, but let me add one more point.

You do not want all of your private variables to have public getters and setters.

Your getters and setters refer to externally visible state. In some cases, what looks like a single object as published in your public methods corresponds to more than one internal private variable for the implementation. In a complex object, many of your private variables won't map to something externally visible. Some people automatically write setters and getters for them anyway, but this is a bad idea because it exposes your implementation details.

Andrew Lazarus
  • 18,205
  • 3
  • 35
  • 53
7

I was always told that one of the main reasons is to try and plan for future changes. It may start out as just

public int getInt() { return _someInt;}

but may end up as

public int getInt() { 
  // do some processing
  return _someInt;

}

and that would save you from having to make massive amounts of changes to where you accessed the public property instead of using the getter/setter.

user12345613
  • 833
  • 9
  • 21
5

Usually a setter allows you to keep restrictions on the type of values being assigned to a private member. So perhaps negative values are not allowed, etc.

A getter, since you've imposed access to the member by making it private for the reasons above, allows consumers access to the value of that member.

Nadir Muzaffar
  • 4,772
  • 2
  • 32
  • 48
  • 2
    And more generally, any behavior (validation, triggering of other actions, etc) attached to the getting or setting of values can be added to a getter or setter without breaking interface compatibility. Using a field, you would have to change interfaces to add behavior. – Chris Shain Aug 26 '11 at 16:52
4

All of the other answers are great and very true. Here is yet another reason why I have found it helpful.

Using the getters and setters on an object is the largest part of following the JavaBean convention. Although following it to the letter is often difficult and overkill, at the very least many third party frameworks/libraries/expression languages depend on the getters and setters convention for accessing the fields of an object. If you follow it up front, then you can already use the objects with these other very useful libraries without having to update your objects.

Examples I have used include:

  • Jsp
  • Freemarker
  • jXls
  • Spring (although Spring is so robust you don't have to follow the convention)
  • SpEL (really any expression language)
jonf
  • 41
  • 2
1

I use regularly getter and setter but apparently we are not doing it right. For example: (obtained from http://java.dzone.com/articles/java-properties-without )

with getter & setter (way long)

public class Teacher {

 @Id @Column(length=5) @Required 
 private String id;

 @Column(length=40) @Required
 private String name;

 @OneToMany(mappedBy="teacher")
 private Collection pupils;

 public String getId() {
     return id;
 }

 public void setId(String id) {
     this.id = id;
 }

 public String getName() {
     return name;
 }

 public void setName(String name) {
     this.name = name;
 }

 public Collection getPupils() {
     return pupils;
 }

 public void setPupils(Collection pupils) {
     this.pupils = pupils;
 }

}

with public: (only 13 lines, counting blank lines).

@Entity
public class Teacher {

 @Id @Column(length=5) @Required 
 public String id;

 @Column(length=40) @Required
 public String name;

 @OneToMany(mappedBy="teacher")
 public Collection pupils;

}

calling with getter & setter (not a bit clear, however C# makes it cleaner).

teacher.setName("M. Carmen");
String result = teacher.getName();

calling public (direct and clean).

teacher.name = "M. Carmen";
String result = teacher.name;

One is verbose and it add more code (and code cost in working hour and in process time), while the other is direct.

In some cases, it is mandatory to use setter and getter but if not, then i think that it is a bit overkill to use it as default.

magallanes
  • 6,583
  • 4
  • 54
  • 55
  • Nice article. But really, if you read through it you notice that in order for this to be a good alternative to getters/setters you will need to include some aspectJ code in your project and use the aspectJ compiler... Plus you then lose all portability with most third party frameworks. – grinch Nov 06 '13 at 02:15