Tips
"Effective Java, third Edition" an English version has been published, the second edition of this book presumably many people have read, known as one of the four major Java books, but the second edition of 2009 published, to now nearly 8 years, but with Java 6, 7, 8, and even 9 of the release, the Java language has undergone profound changes.
In the first time here translated into Chinese version. For everyone to learn to share.
16. Using access methods instead of public properties in public classes
Sometimes, you might try to write some degenerate classes (degenerate classes) that are not useful in addition to centralizing instance properties:
// Degenerate classes like this should not be public!class Point { public double x; public double y;}
Because the data properties of these classes can be accessed directly, these classes do not provide encapsulation benefits (entry 15). If you do not change the API, you cannot change its representation, you cannot enforce invariants, and you cannot perform secondary operations when accessing properties. Insisting that object-oriented programmers feel that such classes are offensive and should be replaced by classes with private properties and public access methods (getter), and for mutable classes, they should be replaced with setter-valued methods:
// Encapsulation of data by accessor methods and mutatorsclass Point { private double x; private double y; public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public double getY() { return y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; }}
Of course, for public classes, sticking to object-oriented is correct: If a class is accessible outside its package, it provides an access method to preserve the flexibility of changing the internal representation of the class. If a public class exposes its data properties, it is virtually impossible to change its representation later because client code can be scattered in many places.
However, if a class is a package-level private, or a private inner class, there is no intrinsic error in exposing its data properties -assuming they provide enough abstraction to describe the class provided. In the client code where the class defines and uses it, this method produces less visual confusion than the access method. Although the client code is bound to the internal representation of the class, the code is limited to the package that contains the class. If the internal representation of a class is desirable, you can make changes without touching any code outside the package. In the case of a private inner class, the change scope is further limited to the enclosing class.
Several classes in the Java Platform Class Library violate the recommendation that public classes should not expose properties directly. Examples of names include the java.awt and classes in the package Point
Dimension
. These categories should be considered as cautionary examples, rather than examples of imitation. As described in entry 67, the Dimension
decision to expose the internal structure is a serious performance problem that still exists today.
While it is not a good idea to expose properties directly to public classes, if the properties are immutable, the damage is less significant. When a property is read-only, you cannot change the internal representation of the class, or take some auxiliary behavior, except to change the API of the class, but you can enhance the invariance. For example, the following example guarantees that each instance represents a valid time:
// Public class with exposed immutable fields - questionablepublic final class Time { private static final int HOURS_PER_DAY = 24; private static final int MINUTES_PER_HOUR = 60; public final int hour; public final int minute; public Time(int hour, int minute) { if (hour < 0 || hour >= HOURS_PER_DAY) throw new IllegalArgumentException("Hour: " + hour); if (minute < 0 || minute >= MINUTES_PER_HOUR) throw new IllegalArgumentException("Min: " + minute); this.hour = hour; this.minute = minute; } ... // Remainder omitted}
In summary, a public class should not expose a mutable property. Although there are still some problems, the harm of the non-variable property of public exposure is less harmful. However, sometimes a package-level private or private inner class is required to expose properties, whether or not this class is mutable.
Effective Java Third Edition--16. Using access methods instead of public properties in public classes