This question has puzzled me for a while. A public property that can be accessed directly or a private property with getter? Which one is better/correct and why?
问题:
回答1:
Exposing fields directly is considered a bad practice.
It is better to keep the field private and only expose the getter and setter. One advantage is that you can choose different access levels for the getter and setter, whereas a field has only a single access level. Another advantage of using getters is that it allows you to change the implementation without changing the class interface.
Even better is to avoid getters and setters where possible. Instead use methods that encapsulate a higher-level behaviour. This is because objects shouldn't be tampering with other objects' internal state (either via directly accessing fields, or indirectly via getters and setters).
Related
- Are getters and setters poor design? Contradictory advice seen
回答2:
Private properties with getters (and possibly setters) are considered proper style since declaring them public and using them directly harms the principle of encapsulation. One of the issues it can cause is that you rely directly on the implementation type of the field, making it harder to change later if the need should arise.
Besides, getters/setters allow you to add logic to the process of accessing and mutating. You could perform boundary checks, input validation, substituting nulls with default values...
Then again, in many cases, like most JavaBeans usage, the getters/setters do nothing more than what you'd do with direct access. So this entire thing is kind of contested in the JavaBeans context.
My opinion? The entire matter is severely overstated and the amount of discussion it has sparked has eaten enough time and keyboard strokes to create an entirely new Java Language Spec with proper properties. Don't listen to dogma, do what works best for you and never stop thinking about what does and doesn't make sense. If everybody just accepted the words from above, we'd probably still be coding in assembly.
回答3:
Generally it's preferred to use getters rather than public fields because making the field private and exposing a getter prevents callers from being able to modify the field, and allows you to change the implementation later without changing the interface.
One exception to this rule is for logical constants, for which people generally prefer public static final fields: Days.SATURDAY
rather than days.getSaturday()
, for instance. But if the value is attached to a particular instance rather than a class, or could ever change, or generally doesn't feel like it must be a universal constant, the flexibility provided by private field / public getter makes it preferable.
回答4:
Keeping the field private prevents other classes from modifying your object, think of an inheritance model where a child can manipulate its parent's fields.
回答5:
Try always to declare fields as private. Suppose you have a bank account and you want to draw some cash:
public class BankAccountWithprivateField
{
private Cash cash;
// ...
public void draw(int amount)
{
if(amount <= balance) cash.draw(amount);
else sentMessage("Sorry your balance is less than what you request!");
}
}
// ...
new BankAccountWithprivateField().draw(500);
Here you cannot draw more than what you have in your balance.
public class BankAccountWithPublicField
{
public Cash cash;
// ...
}
// ...
new BankAccountWithPublicField().cash.draw(1000000);
But here, you can draw 1 million dollar ;)