3

有效的 Java - Item-2 状态

JavaBean 在其构造过程中可能处于不一致的状态。

我无法理解这一点,如果在方法中构造对象,那将如何不一致,如果必须发生异常,也可能在构造函数中发生。这与线程有什么关系?

4

2 回答 2

3

书中介绍了以下 bean:

NutritionFacts cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setServings(8);
cocaCola.setCalories(100);
cocaCola.setSodium(35);
cocaCola.setCarbohydrate(27);

其中,servingSizeand servingsset by setServingSize(int)andsetServings(int)是营养成分的基础——至少在书中是这样。

但如果你只是打电话:

NutritionFacts cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setCalories(100);

那么该servings字段将不会被设置。因此,生成的实例现在处于无效状态。

因此,如果您调用一个需要有效实例的方法,healthRiskCalculator.calculateHealthRisk(NutritionFacts facts)那么您将在对象内或在healthRiskCalculator.

因此,现在您可以在调用时检查对健康的损害,calculateHealthRisk()但可能有许多方法读取或使用对象实例。此外,您可能还为其他产品创建了许多无效实例。换句话说,这不是快速失败

因此,没有使用 bean 创建构造对象的故障安全方法。这不是线程特有的,您可以在单个线程中创建无效的 bean 实例。

于 2014-06-01T00:12:23.967 回答
1

想象一个线程模型,它ThreadUtils.doFoo(FooBean fb)会在哪里产生一个可以与fb. fb可以像传递给该线程以定义其计算的参数一样简单。现在,采用以下构造函数:

public FooBean(int i, int j, int k, int l, int port){
    ThreadUtils.doFoo(this);
    someListField = Arrays.asList(i, j, k, l);
    this.port = port;
}

这会导致this从构造函数中泄漏。如果出于某种虚假原因,生成的线程在列表被正确实例化和分配之前起作用,那么您将有一个线程在this. 例如,如果port新线程使用新线程侦听套接字并被this泄露,则套接字可能会侦听端口 0(数字字段的默认值),而不是端口port

事实上,如果构造函数中的异常this被泄漏并从其他地方获得可访问的强引用,则可能会成为问题。

但是,以下构造函数是安全的:

public FooBean(int i, int j, int k, int l, int port){
    someListField = Arrays.asList(i, j, k, l);
    this.port = port;
    ThreadUtils.doFoo(this);
}

这是因为在 Java 内存模型中,字段甚至在线程生成之前就已存储。

于 2014-04-19T12:04:49.897 回答