Why do we declare private fields when we have acce

2020-02-14 07:22发布

问题:

If I create a class in Java, I've always been taught that the convention is to make all fields of a class private. If I need to access or change them, I can create an accessor and mutator method. I do understand the importance of private variables, as they help reduce complexity and allow for encapsulation.

What I don't understand is that if I create a public accesor and mutator method, isn't the variable public at that point? Why is it still convention to use private variables in situations where anyone can access them?

I should also note that I understand the important of these methods, but I would like to know why we bother to make the variable private even though we are giving anyone access to it through those methods?

回答1:

Yes, you're right, it does effectively make the variable public. But there's one important difference, which is that it gives you the ability to change things later on: you can remove the setter if you want, or make it private, without affecting code that reads from the field using the getter.

If you'd just made the variable public, you wouldn't be able to stop writes to the field without also breaking reads from the field.

It has other advantages. You can make the access synchronized if you want to later on, without breaking client code, for instance. In short, it allows lots of modifications later on that wouldn't otherwise be possible without causing lots of breakages in code that uses the class.

And you can add extra logic that logs whenever someone writes to the field, or prevents certain threads from writing, or whatever... you can change the type of a field from a HashMap to a TreeMap if your getter abstracts it away and just returns a Map... etc.



回答2:

Private fields are considered to be internal to the object. So the outside world doesn't need to know about how the data is stored inside the object. This means you can easily change the internal representation of data of an object while everyone else still uses the same accessors / mutators to do its work.

It's also possible that accessors / mutators perform validation and other steps that are needed internally for the object but that you don't wish to expose to code that uses the object.

You could make all fields public but that limits your ability to change the internal structure of the object later on when a lot of code now depends on a field being named a certain way.