Why Are Getter and Setter Method Important in Java

Why are getter and setter method important in java?

The basic "private field with public getter and setter that do nothing but return or set the field" pattern is indeed completely pointless when it comes to encapsulation, except that it gives you a chance to change it later without changing the API.

So don't use that pattern unthinkingly. Carefully consider what operations you actually need.

The real point of getters and setters is that you should only use them where they are appropriate, and that they can do more than just get and set fields.

  • You can have only a getter. Then the property is read only. This should actually be the most common case.
  • You can have only a setter, making the property configurable, but communicating that nothing else should depend on its value
  • A getter can compute a value from several fields rather than return one field.
  • A getter can make a defensive copy
  • A getter can perform an expensive fetch operation lazily and use a field to cache the value
  • A setter can do sanity checks and throw IllegalArgumentException
  • A setter can notify listeners of changes to the value
  • You can have a setter that sets multiple fields together because they belong together conceptually. This doesn't adhere to the JavaBeans specification, so don't do it if you depend on frameworks or tools that expect JavaBeans. Otherwise, it's a useful option.

All of these things are implementation details that are hidden behind the simple "getter and setter" interface. That's what encapsulation is about.

Why use getters and setters/accessors?

There are actually many good reasons to consider using accessors rather than directly exposing fields of a class - beyond just the argument of encapsulation and making future changes easier.

Here are the some of the reasons I am aware of:

  • Encapsulation of behavior associated with getting or setting the property - this allows additional functionality (like validation) to be added more easily later.
  • Hiding the internal representation of the property while exposing a property using an alternative representation.
  • Insulating your public interface from change - allowing the public interface to remain constant while the implementation changes without affecting existing consumers.
  • Controlling the lifetime and memory management (disposal) semantics of the property - particularly important in non-managed memory environments (like C++ or Objective-C).
  • Providing a debugging interception point for when a property changes at runtime - debugging when and where a property changed to a particular value can be quite difficult without this in some languages.
  • Improved interoperability with libraries that are designed to operate against property getter/setters - Mocking, Serialization, and WPF come to mind.
  • Allowing inheritors to change the semantics of how the property behaves and is exposed by overriding the getter/setter methods.
  • Allowing the getter/setter to be passed around as lambda expressions rather than values.
  • Getters and setters can allow different access levels - for example the get may be public, but the set could be protected.

What is the point of getters and setters?

Multiple reasons:

  • If you allow field access like

    shape.x = 90

then you cannot add any logic in future to validate the data.

say if x cannot be less than 100 you cannot do it, however if you had setters like

public void setShapeValue(int shapeValue){
if(shapeValue < 100){
//do something here like throw exception.
}
}
  • You cannot add something like copy on write logic (see CopyOnWriteArrayList)
  • Another reason is for accessing fields outside your class you will have to mark them public, protected or default, and thus you loose control. When data is very much internal to the class breaking Encapsulation and in general OOPS methodology.

Though for constants like

public final String SOMETHING = "SOMETHING";

you will allow field access as they cannot be changed, for instance variable you will place them with getters, setters.

  • Another scenario is when you want your Class to be immutable, if you allow field access then you are breaking the immutability of your class since values can be changed. But if you carefully design your class with getters and no setters you keep the immutability intact.

Though in such cases you have to be careful in getter method to ensure you don't give out reference of objects(in case your class have object as instances).

We can use the private variables in any package using getters and setters.

What is the point of setters and getters in java?

The point of getters and setters, regardless of language, is to hide the underlying variable. This allows you to add verification logic when attempting to set a value - for example, if you had a field for a birth date, you might only want to allow setting that field to some time in the past. This cannot be enforced if the field is publicly accessible and modifyable - you need the getters and setters.

Even if you don't need any verification yet, you might need it in the future. Writing the getters and setters now means the interface is kept consistent, so existing code won't break when you change it.

Why setter and getter methods

The practice of automatically, unthinkingly creating getX() and setX() methods for every variable is bad. It's mostly pointless, as you have observed.

But it's the unthinking part that's bad. Methods are infinitely better than exposed variables because, again, as you observed, you can control how the underlying data is accessed. If you think about what you're doing, and apply mutators and accessors as appropriate, they're a wonderful tool:

  • You can restrict clients to only reading, but not writing to a variable.
  • You can restrict the values of an integer to only positive values (for example).
  • You can ensure that one variable is always equal to one-half the value of another (for example).
  • You can ensure that, any time the value of a variable is changed, an event is sent to notify other clients.
  • You can change the data type of an underlying variable, perform conversions in the public methods, and not break any clients.
  • You can convert an object to a remote client for a server-side version of the same object, and again, the client code won't change.
  • You can ensure strict memory ordering across threads by using synchronized accessors.

These are only some of the things you can do with mutators and accessors. By using them, you make your software easy to change and easy to maintain.

Are getters and setters poor design? Contradictory advice seen

There is also the point of view that most of the time, using setters still breaks encapsulation by allowing you to set values that are meaningless. As a very obvious example, if you have a score counter on the game that only ever goes up, instead of

// Game
private int score;
public void setScore(int score) { this.score = score; }
public int getScore() { return score; }
// Usage
game.setScore(game.getScore() + ENEMY_DESTROYED_SCORE);

it should be

// Game
private int score;
public int getScore() { return score; }
public void addScore(int delta) { score += delta; }
// Usage
game.addScore(ENEMY_DESTROYED_SCORE);

This is perhaps a bit of a facile example. What I'm trying to say is that discussing getter/setters vs public fields often obscures bigger problems with objects manipulating each others' internal state in an intimate manner and hence being too closely coupled.

The idea is to make methods that directly do things you want to do. An example would be how to set enemies' "alive" status. You might be tempted to have a setAlive(boolean alive) method. Instead you should have:

private boolean alive = true;
public boolean isAlive() { return alive; }
public void kill() { alive = false; }

The reason for this is that if you change the implementation that things no longer have an "alive" boolean but rather a "hit points" value, you can change that around without breaking the contract of the two methods you wrote earlier:

private int hp; // Set in constructor.
public boolean isAlive() { return hp > 0; } // Same method signature.
public void kill() { hp = 0; } // Same method signature.
public void damage(int damage) { hp -= damage; }

When is getters setters needed in android studio project?

Getter and Setter methods are used for encapsulate the data.
it means wrapping the data into single unit.

For example create a ListView with 3 TextView who has different-different value.

so now the question is how will you send the data to your custom ListView adapter. In this case you have to use a beam(has getter-setter methods) class.

EDIT:

Here is another example it will show how to send multiple data by single object from one Activity to another Activity

https://stackoverflow.com/a/7827593/6676466

Can understand setters and getters in java

You asked for a simple example, so I'll give one. Suppose you're designing a circle class. A circle can be characterized by its diameter:

public class Circle {
private double diameter;

public Circle(double diameter) {
this.diameter = diameter;
}
}

A caller might want to know the diameter of the circle, so you add a getter:

public class Circle {
private double diameter;

public Circle(double diameter) {
this.diameter = diameter;
}

public double getDiameter() {
return this.diameter;
}
}

You might also want to get the area of the circle, so you add a getter for the area:

public double getArea() {
return Math.PI * (this.diameter / 2) * (this.diameter / 2);
}

And then you realize that using the radius rather than the diameter is easier for the internal methods of the circle. But you want to keep all the users of your class as is, to avoid breaking a lot of existing code. So you change the internals of the class without changing the interface:

public class Circle {
private double radius;

public Circle(double diameter) {
this.radius = diameter / 2;
}

public double getArea() {
return Math. PI * radius * radius;
}

public double getDiameter() {
return this.radius * 2;
}
}

And finally, you would like to change the diameter of the circle, so you add a setter:

public void setDiameter(double diameter) {
this.radius = diameter / 2;
}

But wait, a circle with a negative diameter makes no sense, so you make the method safer:

public void setDiameter(double diameter) {
if (diameter <= 0) {
throw new IllegalArgumentException("diameter must be > 0");
}
this.radius = diameter / 2;
}

Had you precomputed the area at construction time, the setDiameter would have had to change the value of the area as well:

public class Circle {
private double radius;
private double area;

public Circle(double diameter) {
this.radius = diameter / 2;
this.area = Math. PI * radius * radius;
}

public double getArea() {
return area;
}

public double getDiameter() {
return this.radius / 2;
}

public void setDiameter(double diameter) {
this.radius = diameter / 2;
// the area must also be changed, else the invariants are broken.
this.area = Math. PI * radius * radius;
}
}

Getters and setters are just methods. But they follow a naming conventions that makes your code easy to grasp, and usable by a number of frameworks which rely on these conventions.

What are the uses of getter/setters in Java?

In order to get a stable API from the first shot. The Java gurus thought that if later on, you might want to have some extra logic when setting/getting an instance member, you don't want to break existing API by replacing public fields with public methods. This is the main reason in Java.

In the case of C#, public properties are used instead of public fields because of binary interface compatibility. Someone asked a similar question right here, on SO.

So, it's all about encapsulating some logic while still preserving interface for... future proofing.



Related Topics



Leave a reply



Submit