1

I have a class called Student and here is the code:-

public class Student {
    public String name;
}

And from another class, I access the name.

public class Example {
    public static void main(String[] args) {
        Student s = new Student();
        s.name = "David";
        System.out.println(s.name);
    }
}

But I have heard and seen many codes in many books where they say to make the variables private and use methods to access them like:-

public class Student {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

And,

public class Example {
    public static void main(String[] args) {
        Student s = new Student();
        s.setName("David");
        System.out.println(s.getName());
    }
}

I want to know WHY and what's the DIFFERENCE between them. Why is using methods to manipulate state considered healthier?

Makoto
  • 104,088
  • 27
  • 192
  • 230
61 Keys to Music
  • 127
  • 1
  • 1
  • 8
  • And just for the record : please read my comment on the accepted answer. The answer is good, but it misses one crucial aspect: you don't come in after a year and **change** existing code like that. Real world systems are enhanced (with new code, and maybe subclasses to override specific methods) not changed. Changes like proposed here lead to a high risk of breaking things! – GhostCat Dec 29 '18 at 08:33

5 Answers5

2

There are few intuitive factors for providing getter and setter.

  1. You will have concrete control over what is stored. You can store a different value from that of the incoming value in your internal data structure using computation and you can do validation of the data based on your business logic.

  2. Since you are hiding the data using setter, at any point in time if you want to change the business logic that computes the ultimate/desired data stored or if you want to change the data type of your internal data structure, you can do so without affecting/changing the client code or user code. The benefits are numerous especially when you are writing libraries which will have n number of clients or users.

  3. This is also key for the Oops concepts and design of data hiding and abstraction.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
OTM
  • 656
  • 5
  • 8
2

Letting your class fields be public by default is not a good practice. A public field can be accessed by anyone. Therefore, you cannot ensure that the value you set once is the same you're going to get after.

There's a few ways you can assign values to your instance's fields. One is through the Constructor method:

public class Student {
    private String name;

    public Student(String name){
        this.name = name;
    }

    public void getName(String name) {
        return name;
    }
}

Note that you need a getter method (getName) to access your private field.

Another way would be using setters and getters, as you mentioned, but this faces the same problem that we are trying to avoid using private fields.

1

Because if your variable is public, it can get changed to whatever you like and nothing checks what that value is. When using a setter, before assigning the variable to whatever the programmer wants, the method can check whether whatever gets passed to it is a viable value. For example, it can check whether the passed value is null.

The getter method is just necessary since the variable is private and so solely accessible through a getter function.

However, we can also check different things in getter methods, for example if the variable to be accessed has been initialised or not.

DWuest
  • 619
  • 1
  • 7
  • 18
1

First of all, it is never healthy when you allow other objects to directly manipulate the inner state like that.

As the other answer outlines, using a setter at least allows you to ensure some form of control (such as checking for null values passed down, or thread synchronization) but it is still not good practice.

Fields should be a private implementation detail of your classes, if at all, you provide getter methods. But the idea to have public fields, or to have getters and setters for all fields by default is simply wrong.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
1

Think, after 2 weeks (months, years) from now when you realize that your setter needs to do more than just set the value, you'll also realize that the property has been used directly in 238 other classes, then you have change in 238 lines.

Or If you want to set default value in the set method or if you want to add more business logic in setter or getter method then direct usage is not possible for that case. Lets say you had a setSpeed(int speed) method. But you want that you can only set a maximum speed of 100. You would do something like:

public void setSpeed(int speed) {
  if ( speed > 100 ) {
    this.speed = 100;
  } else {
    this.speed = speed;
  }
}

Now what if EVERYWHERE in your code you were using the public field and then you realized you need the above requirement? Have fun hunting down every usage of the public field instead of just modifying your setter.

Rakib Hasan
  • 317
  • 1
  • 5
  • A good point, but on the other hand hand, your example is also a good hint why doing such things is dangerous. **Changing** the behavior of your code like in your example means that the hundreds of lines that used that setter before might no lead to the expected result suddenly. The caller of that method expects that it sets a specific value. Changing the contract of that method later on can invalidate all usages of that code. And the name would be misleading then, too. The method would be setCheckAndUseDefault or something! – GhostCat Dec 29 '18 at 08:28