gpt4 book ai didi

java - Java Bean 类的缺点是什么?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:05:53 25 4
gpt4 key购买 nike

我从Effective Java这本书中阅读了下面提到的这两个声明

第一名

Unfortunately, the JavaBeans pattern has serious disadvantages of its own. Because construction is split across multiple calls, a JavaBean may be in an inconsistent state partway through its construction.The class does not have the option of enforcing consistency merely by checking the validity of the constructor parameters. Attempting to use an object when it’s in an inconsistent state may cause failures that are far removed from the code containing the bug, hence difficult to debug.

第二名

A related disadvantage is that the JavaBeans pattern precludes the possibility of making a class immutable (Item 15), and requires added effort on the part of the programmer to ensure thread safety. It is possible to reduce these disadvantages by manually “freezing” the object when its construction is complete and not allowing it to be used until frozen, but this variant is unwieldy and rarely used in practice. Moreover, it can cause errors at runtime, as the compiler cannot ensure that the programmer calls the freeze method on an object before using it.

,我无法理解这两个语句到底想表达什么,你们能帮我理解上面的语句吗。

更新

我已经阅读了这篇文章的答案(不是全部),大多数社区成员建议我使用 Constructor Pattern 但在同一本书中这些行已经说过

Static factories and constructors share a limitation: they do not scale well to large numbers of optional parameters. Consider the case of a class representing the Nutrition Facts label that appears on packaged foods. These labels have a few required fields—serving size, servings per container, and calories per serving— and over twenty optional fields—total fat, saturated fat, trans fat, cholesterol, sodium, and so on. Most products have nonzero values for only a few of these optional fields.

对于这个场景,我们使用 telescoping constructor模式但是

The telescoping constructor pattern works, but it is hard to write client code when there are many parameters, and harder still to read it.The reader is left wondering what all those values mean and must carefully count parameters to find out. Long sequences of identically typed parameters can cause subtle bugs. If the client accidentally reverses two such parameters, the compiler won’t complain, but the program will misbehave at runtime

这就是为什么建议使用 JavaBeans 而不是 constructor pattern

最佳答案

让我们看看最简单的 Java Bean:

class Person {
private String firstName;
private String lastName;
public String getFirstName() {return firstName;}
public void setFirstName(String firstName) {this.firstName = firstName;}
public String getLastName() {return lastName;}
public void setLastName(String lastName) {this.lastName = lastName;}
}

以下代码创建 Person 的实例并启动它:

Person president = new Person();
p.setFirstName("George");
p.setLastName("Bush");

如你所见:

  1. 初始化确实分为 3 行。这意味着当所有 3 行都完成时对象处于恒定状态,而在此之前处于不一致状态。
    1. 该对象确实是可变的:它调用的值可以通过调用 setter 来更改。

为什么会这样?因为我们的类 Person 不是线程安全的,因此我们不能在不考虑同步的情况下直接在多线程环境中使用它。

这是一个例子。几年前,巴拉克奥巴马成为美国总统。我们如何用代码表达这一点?

p.setFirstName("Barak");
p.setLastName("Obama");

在多线程环境中,当 setFristName() 已完成且 setLastName() 尚未调用时,president 对象处于错误状态然而,因为该对象包含“Barak Bush”,这显然是错误的。

解决方案是什么?让我们让 Person 不可变:

class Person {
private final String firstName;
private final String lastName;
Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

public String getFirstName() {return firstName;}
public String getLastName() {return lastName;}
}

如您所见,无法更改对象中存储的名字或姓氏。字段是 final 并且没有 setter。因此,我们的示例如下所示:

Person president = new Person("George", "Bush");//选举.....president = new Person("巴拉克", "奥巴马");

由于 Person 是不可变的,我们不能重新使用 Person 的旧实例并更改其属性。我们必须改为创建新实例。如果 presidentvolatitle 引用分配是原子的,因此代码是线程安全的。

更新

构造函数的问题在于它们不灵活。我们的示例只有 2 个参数。但想想现实世界中 Person 类可能有 20 个或更多字段。在这种情况下,创建此类对象非常冗长。

此外,有些字段可以是可选的。在这种情况下,您可能希望创建多个具有不同数量参数的重载构造函数。为了避免重复赋值代码,使用所谓的伸缩构造函数是常见的技术,即当构造函数调用其他构造函数时的模式。这种模式很好,但有些过于冗长且难以修改。

这只是意味着没有理想的解决方案。每种解决方案都有自己的优点和缺点。

顺便说一句,将不可变对象(immutable对象)的优点与对象创建和初始化的灵 active 相结合的解决方案是构建器模式。

我不会写出更好地理解这些问题所需的所有示例。但我希望我的回答对你有所帮助。现在您有了一个起点,可以使用其他资源了解这个问题。祝你好运。

关于java - Java Bean 类的缺点是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28394127/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com