Java protected fields vs public getters

What is more good practice and why: access to base class variables through a secure field or public recipient in a private field.

(The recipient will be public regardless)

+58
java
Feb 17 2018-10-17 at
source share
8 answers

If in any case there will be a public getter, why do you want to open the field more widely than absolutely necessary? This means that it is immediately written in subclasses (unless it starts from the end).

Personally, I like that all of my fields are private: it provides a cleaner separation between the API and the implementation. I believe that the relationship between the superclass and the subclass is similar to the relationship of the caller and the called person - changes in the base implementation should not violate the subclasses, but not interrupt them. The field name is an implementation detail that should not affect other classes.

Admittedly, my opinion sometimes seems somewhat extreme ...

+59
Feb 17 2018-10-17 at
source share

You should always program against a public API class, that is, use public methods.

The reason is simple. Sometime in the future, you or someone else will want to change the implementation. It should always be possible. If you rely on an instance variable, you are limiting yourself.

In addition, when accessing a variable, you cannot control whether this variable is read-only, and you cannot add checks when this variable changes.

If you use setters / getters, you can always add validation, validation, etc. later. You can also provide only getter to make only a variable.

+14
Feb 17 2018-10-17T00
source share

Direct access to the field is not preferred. Use public or protected installers and recipients.

The recipient does not have to be public - if you want to hide data from "outsiders", but give data to subclasses, use protected

+9
Feb 17 2018-10-17 at
source share

Some of Sun's guidelines for access control over fields are here. Note that creating a protected field also provides it in a package, not just for subclasses. As a rule, as indicated in the link above, the fields should be closed, unless there is a very good reason not to.

+4
Feb 17 2018-10-17 at
source share

Effective Java 2nd Edition says

Item 13: Minimize the accessibility of classes and members

The thumb rule is simple: make each class or member inaccessible as possible. In other words, use the lowest possible level of access appropriate for the proper functioning of the software you are writing.

So, if you don’t know why you need a protected member of the class (i.e. you do not need the field to be accessible to subclasses or classes in the same package), then declare it private. If you want to install it outside the class then create a public setter.

However, if your member is final, then protection in some cases may be in order (i.e. it does not detect confidential information).

One potential security issue that I would like to mention is that if you have declared protected final (even public final), the reference to the array is final (cannot be modified), but the objects stored in the array are not final (an attacker can modify the contents of an array).




If you know C ++, you probably know that

const int * someMember

differs from

int * const someMember

The latter as the last array in java.




The fix for the above security hole is to return a deep copy of the array or return it as a read-only list.

+4
Dec 11 '11 at 4:45
source share

Generally, you should use the recommendations of Sun. There is one big exception: if you are programming for Android.

The reason is performance. Each time the virtual method is called, problems arise using the lookup table to route the method to its object. This overhead is not involved when accessing a local variable.

Here are a few links that explain this in a bit more detail:

http://developer.android.com/training/articles/perf-tips.html#GettersSetters

http://blog.leocad.io/why-you-shouldnt-use-getters-and-setters-on-android/

It is important to know what you are trying to accomplish:

  • The field value must be accessible to the client code using the open interface.
  • The field is intended for use by subclasses.

In plain ol 'Java, getters and seters perform both tasks. But Android is different. If you are making # 1, you should use public getters and setters. If you do # 2, you should use protected fields. If you use both options, use both options.

+1
Jun 24 '14 at 20:42
source share

Access to protected fields from a subclass is one way to break encapsulation inheritance. For this reason, it is better to use a public API.

0
Feb 17 '10 at 10:27
source share

I would like to introduce some arguments that protect "protected" fields in Java: "You may prefer access to members of the base class using protected fields over public access means in a situation where you need to avoid checking the value." However, if this is not the case, then private fields with public access means should be used to complement the sealing.

The principle of getting and setting is to provide verification of the values ​​entered and displayed for a member of the class. However, in OOP languages ​​we operate on objects, not classes. The base class and the specialized class are one object, so it is perfectly normal to access individual members of the class through a protected field.

Consider the following abstract example with a car: - you have a base class Car and a derived class Porshe. - The Car class may have a field of type engine, the value of which is not set in the Cars constructor (perhaps the type of engine is known only after the object is initialized) - You create an object of the Porshe class that contains some logic used to calculate the type of engine using some external data ,

In this example, the engine field is expected to have an open getter, so car users know which engine the car has. However, there is no public setter, as we expect car drivers to not tune in to work with the engine! That's why it's perfectly normal to make an engine a protected field, so the Porshe class can set its value in the future.

Yes, some people will probably say, "Then use a secure setter!" And again I repeat: in OOP languages ​​we work with objects, not with classes. The principle of common responsibility is yes, but as an object, and not as a class. If you say: "at some point, if we use protected fields with 3 or 5 levels of inheritance, it can be difficult to understand what happens to the field if each class performs an operation on it." And then I answer: this is another antipattern - your object is probably too large at the moment and is losing the principle of a single responsibility.

0
Jan 29 '19 at 13:24
source share



All Articles