问题
If I can change the value of private variable through getter-returned reference then isn't it bypassing the setter method? Doesn't it defeat the purpose of getter-setter and private variables
public class Test{
private Dimension cannotBeChanged;
public Test(int height, int width)
{
if(height!=3)
cannotBeChanged.height = height;
if(width!=3)
cannotBeChanged.width = width;
}
public Dimension getDimension()
{
return cannotBeChanged;
}
public void setDimension(int height, int width)
{
if(height!=3)
cannotBeChanged.height = height;
if(width!=3)
cannotBeChanged.width = width;
}
public static void main(String [] args)
{
Test testOne = new Test(5,5);
Dimension testSecond = testOne.getDimension();
testSecond.height = 3; //Changed height and width to unwanted values
testSecond.width= 3;
}
回答1:
Yes, It does. I have the following conclusion in getters and setters from the Clean Code book; you can use it if you really accept it.
- Very evil: public fields.
- Somewhat evil: Getters and setters where they're not required.
- Good: Getters and setters only where they're really required - make the type expose "larger" behaviour which happens to use its state, rather than just treating the type as a repository of state to be manipulated by other types.
回答2:
The right way would actually be, to provide a setter only for the needed part of the dimension. Like this:
public int getDimensionX()
{
return cannotBeChanged.getX();
}
public int getDimensionY()
{
return cannotBeChanged.getY();
}
回答3:
Here a simple Testcase from me. As you can see you can change the height indeed of a Dimension, because it's a reference, but you can't set a new Dimension.
import java.awt.Dimension;
public class TestProperty
{
private String testy;
private Dimension testDim = new Dimension(2,2);
TestProperty(String testy)
{
this.testy = testy;
}
public String getTesty()
{
return testy;
}
public void setTesty(String testy)
{
this.testy = testy;
}
public Dimension getTestDim()
{
return testDim;
}
public void setTestDim(Dimension testDim)
{
this.testDim = testDim;
}
}
My main()-method:
import java.awt.Dimension;
public class Test
{
public static void main(String[] ARGS)
{
TestProperty testy = new TestProperty("Testy");
String myString = testy.getTesty();
Dimension myDimension = testy.getTestDim();
myDimension.height = 5; //Changes the height of the private Dimension
myDimension = new Dimension(5,3); //Does not set a new Instance of Dimension to my TestProperty.
myString = "Test";
System.out.println(myString+"|"+testy.getTesty());
System.out.println(myDimension.height+"|"+testy.getTestDim().height);
}
}
Output:
Test|Testy
3|5
回答4:
Private variables are meant to be accessed only from the class it was declared. When you create the getter method that returns the value of the private variable you are not getting the address but instead creating a temporary copy that holds the value of the returned value. The setter method sets a value to the private variable which can't be done when it's from another class.
So basically the getter-setter methods are for when you are trying to access or modify private variables from another class.
Note: The width and height values you are modifying are the variables from the Dimension class so they are public not private.
Take a look at this example:
public class Test {
private double width, height;
public Test(int height, int width)
{
setDimension(height, width);
}
public double getWidth() { return width; }
public double getHeight() { return height; }
public void setDimension(int height, int width)
{
if(height!=3)
this.height = height;
if(width!=3)
this.width = width;
}
public static void main(String [] args)
{
Test test = new Test(5,5);
double testW = test.getWidth();
testW = 3;
System.out.println(testW);
System.out.println(test.getWidth());
}
}
Returns:
3.0
5.0
回答5:
Programmer should devise the ways for external entities to touch the secured variables of his program.
- Never create any setter for a secured property of your object. Only a getter can be provided.
- Create setters only for those properties, which can change during the course of program.
- Use setters if you want to apply certain restrictions on some properties e.g. apply invalid value checks, pre-population, logical analysis, populating another depending property, defensive copying etc
- Getters/setters helps in maintaining the software entropy of a system. Read about software entropy.
- Do not create getters/setters where it is not required as its leads to Boilerplate code.
- Getters/setters helps in changing the underlying implementation for future Extensions of Programs e.g. Upgrading Logging libraries etc
来源:https://stackoverflow.com/questions/22008180/getter-setter-and-private-variables