【问题标题】:Static factory method does not work静态工厂方法不起作用
【发布时间】:2018-10-22 21:08:51
【问题描述】:

开始阅读“Effective java”,不明白为什么当我尝试编写示例时它对我不起作用..

编译错误:

Error:(12, 16) java: 类 Car 中的构造函数 Car 不能应用于 给定类型;


public class Car {

    String model;

    //no private constructor

    public static Car fromModel(String model) {
        return new Car(model);
    }

}

这里一切正常:

public class Car {

    String model;

    //no private constructor

    public static Car fromModel(String model) {
        return new Car(model);
    }
}

//Here everything is OK:

public class Car {

    String model;

    private Car(String model) {
        this.model = model;
    }

    public static Car fromModel(String model) {
        return new Car(model);
    }

}

如果“考虑静态工厂方法而不是构造函数”,我为什么要生成构造函数???

【问题讨论】:

  • 你为什么会期待第一部作品?您正在调用一个不存在的构造函数。

标签: java effective-java


【解决方案1】:

“考虑静态工厂方法而不是构造函数”是指向您的类外部类的用户提供对对象实例化的访问。

您的工厂方法使用的构造函数是您的工厂方法的实现细节,与static public 方法相同 - 该方法和私有构造函数共同构成了一个工厂方法,供您的类库的外部用户使用。

【讨论】:

  • 如果我理解正确,我必须有一个包含所有变量的私有构造函数,然后可以有几个私有静态方法?
  • @mnjl 虽然这是实现该模式的一种非常常见的方式,但具体情况取决于您。如果对您更方便,您可以定义多个私有构造函数。
【解决方案2】:

我的答案是我至少需要一个私有构造函数来创建几个静态方法。

没有编译错误:

public class Car {

String model;
String color;
String modelYear;

private Car(String model, String color, String modelYear) {
    this.model = model;
    this.color = color;
    this.modelYear = modelYear;
}

public static Car fromModelAndColor(String model, String color){
    return new Car(model, color, null);
}

public static Car fromModelAndYear(String model, String modelYear){
    return new Car(model, null, modelYear);
}

public static Car fromModelAndColorAndYear(String model, String color, String modelYear){
    return new Car(model, color, modelYear);
}

}

【讨论】:

  • 在我认为我不需要任何构造函数之前,因为:“考虑静态工厂方法而不是构造函数”。现在我可以看到我被误导了......上面的讨论大大澄清了我的问题。我刚刚编辑了我的答案。
【解决方案3】:

你的例子可能很简单。普通构造函数可能有大量参数。在这种情况下,您可以通过创建静态构造方法来“命名”每个构造方法。其次,使用这种模式可以隐藏部分构造函数参数。

例子:

class FinishEvent {
   privare Car response;
   private boolean success;
   private String errorMessage;

  //private constructor, we delegate creating to named methods
   private FinishEvent(Car response, boolean success, String errorMessage) {... } 

}

你可以看到 Car 在这里是一个响应,但是当 Event 成功时,我们不需要填充 errorMessage。另一方面,如果流程失败,我们没有响应填写。

这里静态构造方法就派上用场了:

public static FinishEvent success(Car response){
  return new Car(response, true, null);
}
public static FinishEvent failed(String errorMessage){
  return new Car(null, false, errorMessage);
}

有这个 API 你班的其他用户,知道如何使用它。

如果您的 Car 是一个抽象方法,那么您的工厂方法可以提供实现。这样您就可以对用户隐藏所有实现,但提供一种创建它们的方法。

【讨论】:

  • 假设我明白了。请在下面查看我被否决的答案,根据您的解释,它看起来对我来说是正确的......谢谢!
  • @mnjl 是的,你的答案是正确的,但没有解释的粘贴代码不算作答案。可能是复制粘贴,也可能是其他抄袭。请添加一些 cmets:)
  • 完成了,如果还有不明白的地方请反馈。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-04
  • 1970-01-01
相关资源
最近更新 更多