【问题标题】:How do I make sure to initialize only one Instance but from another class?如何确保只初始化一个 Instance 但从另一个类初始化?
【发布时间】:2018-05-22 17:18:55
【问题描述】:

我最近阅读了有关单例原理的文章,但我不太明白如果构造函数是private,我如何从另一个类中初始化一个类的单个实例。如果构造函数应该是private,我该如何设置另一个类的参数?

public class Player {

    String name;
    Position p;
    Inventory i;

    private Player(String name, Position p, Inventory i){

    }

    static {
        instance = 
    }

    public static Player getPlayer(){
        return instance;
    }

}

【问题讨论】:

  • 那你还没有正确理解单例。在单例中没有 setter 方法。成员变量在实例创建时设置。

标签: java constructor singleton


【解决方案1】:

您应该创建一个private static Player 变量,并在您的getPlayer() 方法或静态块中创建对象并分配给上述变量(如果它为空)。

public static Player getPlayer(){
    if(player == null){
        player = new Player("name", p, i);
    }
    return player;
}

这样你只创建一个实例。


简单的规则,

  1. 类的构造函数应该是private
  2. 将对象保存在 private static 变量中。
  3. 为单例对象创建一个 getter(无 setter)。
  4. 您还可以将 synchronized 添加到 getter 以使其线程安全(可选)。

【讨论】:

  • 此代码不是线程安全的。多个线程可能会看到 playernull 并初始化不同的 Player 实例。而且,默认构造函数没有声明,你不能使用它
  • 我可以为对象属性创建设置器还是违反单例原则?
  • @FabianZbinden 没关系,只要唯一的静态对象是您的 Player 对象。这意味着所有其他变量都在该对象内。
【解决方案2】:

在你打电话的另一个班级:Player.getPlayer()

它总是返回你的类的唯一一个静态实例。构造函数是私有的,因此其他类无法通过构造函数初始化您的类。

获取Player 实例的唯一方法是通过静态方法Player.getPlayer(),因此它是单例的。

public class Player {

    String name;
    Position p;
    Inventory i;


    private static final Player instance = new Player(.....your argument....);

    private Player(String name, Position p, Inventory i){

    } 

    public static Player getPlayer(){
        return instance;
    }

}

【讨论】:

  • 我需要getters 才能访问会员
【解决方案3】:

基本上,通过这种方法,您可以隐藏构造函数 (private) 并公开获取 instance 的静态方法。在方法中检查instance 是否为null,如果是,则使用提供的参数对其进行初始化。

最后你返回instance

注意如果您多次调用 getPlayer 方法,将使用第一个提供的参数创建实例(并且在进一步调用方法 getPlayer 时相同)调用静态方法的时间。

public class Player {

    String name;
    Position p;
    Inventory i;

    private static Player instance;

    private Player(String name, Position p, Inventory i){
        // ...
    }

    public static Player getPlayer(String name, Position p, Inventory i){
        if (instance == null) {
            instance = new Player(name, p, i);
        }
        return instance;
    }

}

此外,如果您想正确使用单例模式,则不应在创建实例后设置属性(无 setters 方法)。

【讨论】:

    【解决方案4】:

    只需将私有静态 final INSTANCE 字段声明为

    private static final INSTANCE = new Person(name, p, i);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 2012-06-23
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      • 1970-01-01
      相关资源
      最近更新 更多