问题
I have been taught to always use getters and setters. However, I don't know the pros and cons of these methods, as by implementing them we are exposing the data and also hiding it.
I am a little confused about this. Can anybody give some proper advice on why we use a getter/setter and what the advantages are?
回答1:
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.
回答2:
The idea of getters and setters are to control access to variables in a class. That way, if the value needs to be changed internally to be represented in a different way, you can do so without breaking any code outside the class.
For example, let's say you had a class with a distance variable, and it was measured in inches. A few months pass, you're using this class in a lot of places and you suddenly realize you needed to represent that value in centimeters. If you didn't use a getter and a setter, you would have to track down every use of the class and convert there. If you used a getter and a setter, you can just change those methods and everything that uses the class won't break.
public class Measurement
{
/**
* The distance in centimeters.
*/
private double distance;
/**
* Gets the distance in inches.
* @return A distance value.
*/
public double getDistance()
{
return distance / 2.54;
}
/**
* Sets the distance.
* @param distance The distance, in inches.
*/
public void setDistance(double distance)
{
this.distance = distance * 2.54;
}
}
回答3:
One good advantage comes into mind is that you can make a field ReadOnly by not implementing a setter for that particular field.
回答4:
Here's the downside. Getters/Setters tend to expose the implementation details of your class to the outside world. That's not a good thing. Imagine you are writing an Auto mechanic software package. Thus you will need a Car class, and so you expose getters and setters for the fields
Date lastOilChangeDate;
int lastOilChangeMileage;
in this class. This is because the software wants to send emails when customer cars need oil changes.
But what happens when new cars come out where you determine whether a car needs an oil change differently than 'every 3000 miles or 3 months'? Perhaps these new cars have a sensor in the oil pan that measured dirtyness. Obviously you'd want to use this to determine whether an oil change was needed.
The issue was you were solving the wrong problem with those getter/setters. No one really wants to know when the last oil change was, they want to know if you need another one. They were just implementation details, but you made them part of the interface. What you should have done was added a method
public boolean needsOilChange()
and then the Car class could implement however it wanted. If the algorithm change the Mechanic class wouldn't have to because all it needed was the needsOilChange method.
回答5:
There is nothing wrong with using getters and setters - just be aware that by using them and making them all public you're exposing your variables and, in a way, violating encapsulation. This is what the article you mention is trying to warn of - don't just automatically generate getters and setters for all private instance variables; think about what you want to expose to other classes (and at what level, i.e. private/protected/public) so that you're exposing only as needed.
回答6:
this is mostly used in Java beans like below.
public Class MyBean{
private int var1;
public void setVar1(int pVar1){
this.var1=pvar1;
}
public int getVar1(){
return var1;`
}
}
benefits are as below
1. with this we can achieve Encapsulation
2. it is called as DTO (Data Transfer Object) design pattern. it is used to transfer data from one layer to another layer in MVC based applications. like u can get user entered data from form (by using getters) and u can use the same data to insert into database(by using setter) and vice verca. latest frameworks (SPring )providing it as inbuilt functionality.
来源:https://stackoverflow.com/questions/8830772/why-are-getter-and-setter-method-important-in-java