【问题标题】:Private Constructor initialized by a public method由公共方法初始化的私有构造函数
【发布时间】:2013-05-16 03:35:59
【问题描述】:

我遇到了一个带有私有构造函数的类,但该对象是由另一个公共方法通过调用私有构造函数返回的。当我们可以将构造函数公开时,这种构造可能有什么优势?

public final class TokenTable {

    static public int errorToken = 0; 
    static public int timesToken = 1;
    static public int divToken = 2;
    static public int plusToken = 11;
    ......
    ......

    private final HashMap<String, Integer> keywordMap = new HashMap();
    private final HashMap<String, Integer> operationMap = new HashMap();

    private TokenTable() {

        operationMap.put("*", timesToken);
        operationMap.put("/", divToken);
        operationMap.put("+", plusToken);
        ....



    }


    static public TokenTable getInstance() {

            LexTokenTabInstance = new TokenTable();
            return LexTokenTabInstance;
    }

}

【问题讨论】:

  • 我不得不说,我有点失望,这里的大多数答案都是单例。我猜这是getInstance() 的名字(这是单例吸气剂最常见的名字之一)......但仍然如此。
  • @cHao 如果您对当前的答案不满意,为什么不创建自己的答案?如果您觉得有比所提供的更好的答案,我很想读一读。
  • @Supericy:因为这里有两个很好的已经说了我想说的。让我沮丧的是其他人。
  • 你也可以看看这个答案stackoverflow.com/questions/16620832/…,它与静态工厂模式有关。

标签: java constructor public-method


【解决方案1】:

这称为Factory 模式。查看描述here - Factory Design Pattern

有几个优点:

  • 您可以使用多个命名工厂方法来创建不同风格的对象,从而允许使用相同的参数类型集进行重载
  • 如果合适,您可以返回一个单例,也可以返回一组缓存实例中的一个
  • 如果不需要使用new
  • 使用泛型时,泛型类型由编译器推断,因此不需要使用&lt;&gt; 运算符
  • 你可以返回一个接口而不是一个具体的类
  • 允许预构造函数初始化(例如,如果必须在调用基类构造函数之前完成初始化)

为了清楚起见,上面的示例似乎只是作为“良好做法”完成的,因为没有使用上述任何功能(除了您不必使用“新”)。

【讨论】:

  • 可能应该注意的是,在您不需要任何这些优势的地方,普通的公共构造函数携带的精神包袱要少一些。即:不要把所有东西都变成工厂,只是因为它更漂亮。 :)
【解决方案2】:

这称为工厂方法。与构造函数相比,工厂方法有很多优点:

  • 它有一个名字(多个工厂方法可能有不同的名字)
  • 它允许返回缓存实例而不是新实例
  • 它允许返回一个子类实例而不是实际的类

【讨论】:

    【解决方案3】:

    主要优点是没有人可以创建实例,而是使用静态getInstance方法。

    这样你可以确保只创建一个实例,就像Singelton design pattern

    【讨论】:

      【解决方案4】:

      隐藏类的构造函数的主要原因是为了控制如何创建该类的对象。一个常见的例子是 Singleton 模式,其中只实例化一个类的一个对象。

      为了监管这一点,用户访问一个静态方法,如果没有创建对象,该方法将访问私有构造函数,否则返回对已创建对象的引用:

      public class SingletonDemo {
          private static volatile SingletonDemo instance = null;
      
          private SingletonDemo() {       }
      
          public static SingletonDemo getInstance() {
                  if (instance == null) {
                          synchronized (SingletonDemo.class){
                                  if (instance == null) {
                                          instance = new SingletonDemo();
                                  }
                        }
                  }
                  return instance;
          }
      }  
      

      对于其他示例,请查看一般的工厂模式:http://en.wikipedia.org/wiki/Factory_method_pattern

      【讨论】:

        【解决方案5】:

        如果您不想保护在类之外创建多个实例,则可以创建私有构造函数。
        这对创建单个实例很有帮助。
        您可以这样做(急切加载):

        private static final TokenTable tokenTable = new TokenTable();
        
        static public TokenTable getInstance() {
        
                  return tokenTable;
            }
        

        或者,你可以这样做(延迟加载):

        private static TokenTable tokenTable;
        
        static public TokenTable getInstance() {
                 if(null == tokenTable){
                 tokenTable = new TokenTable(); 
                 }
                  return tokenTable;
            }
        

        【讨论】:

        • 注意,延迟加载示例不是线程安全的。 :P 你通常会将函数标记为synchronized,或者在类上显式同步。
        • 好的,Chao,感谢您提供宝贵的信息。
        猜你喜欢
        • 2012-02-04
        • 1970-01-01
        • 2016-11-28
        • 1970-01-01
        • 2011-02-08
        • 2014-06-08
        • 2017-04-30
        • 1970-01-01
        • 2014-04-29
        相关资源
        最近更新 更多