Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update #6

Merged
merged 9 commits into from
Sep 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ To facilitate(vt. 促进;帮助;使容易) testing your code, you may be

**Instance fields of public classes should rarely be public** (Item 16). If an instance field is nonfinal or is a reference to a mutable object, then by making it public, you give up the ability to limit the values that can be stored in the field.This means you give up the ability to enforce invariants involving the field.Also, you give up the ability to take any action when the field is modified, so **classes with public mutable fields are not generally thread-safe.** Even if a field is final and refers to an immutable object, by making it public you give up the flexibility to switch to a new internal data representation in which the field does not exist.

**公共类的实例字段很少是公共的**([Item-16](https://github.com/clxering/Effective-Java-3rd-edition-Chinese-English-bilingual/blob/master/Chapter-4-Item-16-In-public-classes-use-accessor-methods-not-public-fields.md))。如果实例字段是非final的,或者是对可变对象的引用,那么通过将其公开,您就放弃了限制字段中可以存储的值的能力。这意味着您放弃了强制包含字段的不变量的能力。此外,您还放弃了在修改字段时采取任何操作的能力,因此带有公共可变字段的**类通常不是线程安全的。**即使一个字段是final的,并且引用了一个不可变的对象,通过将其公开,您放弃了切换到一个新的内部数据表示的灵活性,而该字段并不存在。
**公共类的实例字段很少是公共的**([Item-16](https://github.com/clxering/Effective-Java-3rd-edition-Chinese-English-bilingual/blob/master/Chapter-4-Item-16-In-public-classes-use-accessor-methods-not-public-fields.md))。如果实例字段是非final的,或者是对可变对象的引用,那么通过将其公开,您就放弃了限制字段中可以存储的值的能力。这意味着您放弃了强制包含字段的不变量的能力。此外,您还放弃了在修改字段时采取任何操作的能力,因此带有公共可变字段的 **类通常不是线程安全的。** 即使一个字段是final的,并且引用了一个不可变的对象,通过将其公开,您放弃了切换到一个新的内部数据表示的灵活性,而该字段并不存在。

The same advice applies to static fields, with one exception. You can expose constants via public static final fields, assuming the constants form an integral part of the abstraction provided by the class. By convention, such fields have names consisting of capital letters, with words separated by underscores (Item 68). It is critical that these fields contain either primitive values or references to immutable objects (Item 17). a field containing a reference to a mutable object has all the disadvantages of a nonfinal field. While the reference cannot be modified, the referenced object can be modified—with disastrous results.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

Occasionally, you may be tempted to write degenerate classes that serve no purpose other than to group instance fields:

偶尔,您可能会忍不住编写一些只用于分组实例字段的退化类:

```
// Degenerate classes like this should not be public!
class Point {
Expand All @@ -12,7 +14,9 @@ class Point {
}
```

Because the data fields of such classes are accessed directly, these classes do not offer the benefits of encapsulation (Item 15). You can’t change the representation without changing the API, you can’t enforce invariants, and you can’t take auxiliary action when a field is accessed. Hard-line object-oriented programmers feel that such classes are anathema and should always be replaced by classes with private fields and public accessor methods (getters) and, for mutable classes, mutators (setters):
Because the data fields of such classes are accessed directly, these classes do not offer the benefits of encapsulation(n. 封装;包装) (Item 15). You can’t change the representation(n. 代表;表现;表示法;陈述) without changing the API, you can’t enforce invariants, and you can’t take auxiliary(adj. 辅助的;副的;附加的) action when a field is accessed. Hard-line object-oriented programmers feel that such classes are anathema(n. 诅咒;革出教门;被诅咒者;令人厌恶的人) and should always be replaced by classes with private fields and public accessor methods (getters) and, for mutable classes, mutators (setters):

因为这些类的数据字段是直接访问的,所以这些类没有提供封装的好处([Item-15](https://github.com/clxering/Effective-Java-3rd-edition-Chinese-English-bilingual/blob/master/Chapter-4-Item-15-Minimize-the-accessibility-of-classes-and-members.md))。不改变API就不能改变表示,不能强制执行不变量,也不能在访问字段时采取辅助操作。强硬的面向对象程序员认为这样的类是令人厌恶的,应该总是被私有字段和公共访问方法(getter)的类所取代,对于可变类,则是mutators (setter):

```
// Encapsulation of data by accessor methods and mutators
Expand All @@ -32,12 +36,20 @@ class Point {

Certainly, the hard-liners are correct when it comes to public classes: if a class is accessible outside its package, provide accessor methods to preserve the flexibility to change the class’s internal representation. If a public class exposes its data fields, all hope of changing its representation is lost because client code can be distributed far and wide.

当然,当涉及到公共类时,强硬派是正确的:如果类可以在包之外访问,那么提供访问器方法来保持更改类内部表示的灵活性。如果一个公共类公开其数据字段,那么改变其表示形式的所有希望都将落空,因为客户机代码可以广泛分发。

However, if a class is package-private or is a private nested class, there is nothing inherently wrong with exposing its data fields—assuming they do an adequate job of describing the abstraction provided by the class. This approach generates less visual clutter than the accessor-method approach, both in the class definition and in the client code that uses it. While the client code is tied to the class’s internal representation, this code is confined to the package containing the class. If a change in representation becomes desirable, you can make the change without touching any code outside the package. In the case of a private nested class, the scope of the change is further restricted to the enclosing class.

但是,如果一个类是包私有的或者是私有嵌套类,那么公开它的数据字段并没有什么本质上的错误——假设它们能够很好地描述类提供的抽象。无论是在类定义还是在使用它的客户机代码中,这种方法产生的视觉混乱都比访问方法少。虽然客户机代码与类的内部表示绑定在一起,但这段代码仅限于包含该类的包。如果想要对表示形式进行更改,您可以在不接触包外部任何代码的情况下进行更改。对于私有嵌套类,更改的范围进一步限制在封闭类中。

Several classes in the Java platform libraries violate the advice that public classes should not expose fields directly. Prominent examples include the Point and Dimension classes in the java.awt package. Rather than examples to be emulated, these classes should be regarded as cautionary tales.As described in Item 67, the decision to expose the internals of the Dimension class resulted in a serious performance problem that is still with us today.

Java平台库中的几个类违反了公共类不应该直接公开字段的建议。突出的例子包括java.awt包中的Point和维度类。这些课程不应被效仿,而应被视为警示故事。正如[Item-67](https://github.com/clxering/Effective-Java-3rd-edition-Chinese-English-bilingual/blob/master/Chapter-9-Item-67-Optimize-judiciously.md)所述,决定公开维度类的内部结构导致了严重的性能问题,这种问题至今仍存在。

While it’s never a good idea for a public class to expose fields directly, it is less harmful if the fields are immutable. You can’t change the representation of such a class without changing its API, and you can’t take auxiliary actions when a field is read, but you can enforce invariants. For example, this class guarantees that each instance represents a valid time:

虽然公共类直接公开字段从来都不是一个好主意,但是如果字段是不可变的,那么危害就会小一些。您不能在不更改该类的API的情况下更改该类的表示形式,也不能在读取字段时采取辅助操作,但是您可以强制执行不变量。例如,这个类保证每个实例代表一个有效的时间:

```
// Public class with exposed immutable fields - questionable
public final class Time {
Expand All @@ -56,4 +68,6 @@ public final class Time {
}
```

In summary, public classes should never expose mutable fields. It is less harmful, though still questionable, for public classes to expose immutable fields.It is, however, sometimes desirable for package-private or private nested classes to expose fields, whether mutable or immutable.
In summary, public classes should never expose(vt. 揭露,揭发;使曝光;显示) mutable fields. It is less harmful, though still questionable(adj. 可疑的;有问题的), for public classes to expose immutable fields.It is, however, sometimes desirable for package-private or private nested classes to expose fields, whether mutable or immutable.

总之,公共类不应该公开可变字段。对于公共类来说,公开不可变字段的危害要小一些,尽管仍然值得怀疑。然而,有时候包私有或私有嵌套类需要公开字段,无论是可变的还是不可变的。