Java——私有构造函数 vs final 等等

Posted

技术标签:

【中文标题】Java——私有构造函数 vs final 等等【英文标题】:Java -- private constructor vs final and more 【发布时间】:2013-09-02 14:42:53 【问题描述】:

假设有一个类,它的所有构造函数都声明为私有。

例如:

public class This 
    private This ()  

    public someMethod( )
    // something here
    
   // some more-- no other constructors

据我所知,将所有构造函数设为私有类似于将“This”类声明为final——因此它不能被扩展。

但是,我收到的 Eclipse 消息给我的印象是这是可能的——可以扩展一个全构造函数私有类。看看这个:

当我尝试用类似的东西扩展这个类时

public class That extends This 
    ...

Eclipse 给我一个错误:“隐式超级构造函数 This() 对于默认构造函数不可见。 必须定义一个显式的构造函数。"

当我定义自己的构造函数时:

public class That extends This 
    That () .. 
    ...

这一次我得到: "隐式超级构造函数 This() 对于默认构造函数是不可见的。 必须显式调用另一个构造函数。"

有没有办法解决这个问题——扩展一个所有构造函数都是私有的类?

如果是,怎么做?

如果不是,那么阻止一个类被扩展有什么区别 i.) 将其构造函数设为私有,并且 ii.) 将其定义为 final

注意:我在其他一些讨论中看到了Can a constructor in Java be private?。

【问题讨论】:

【参考方案1】:

具有私有构造函数的类不能被实例化,除非在同一个类中的形式。这使得从另一个类扩展它是无用的(可能,但不会编译)。

这并不意味着它根本不能被子类化,例如在内部类中你可以扩展和调用私有构造函数。

【讨论】:

好点,但最后的陈述有点模糊。您可以对类进行子类化,但不能在子类中调用私有构造函数。它是私有的,不受保护。但是,是的。如果原类内部有一个带私有构造函数的内部类,可以调用原类的私有构造函数。不确定它的用途,但它是合法的。 层次结构或多或少是包 -> 类 -> 内部类。类私有的,内部类可以访问。您可以使用私有构造函数和它的一些内部子类声明一个抽象内部类,并在主类中使用它们。这不是世界上最有用的东西,但如果你想这样做,你可以。【参考方案2】:

您声明一个类 final 与创建其构造函数 private 的原因不同:

您创建类final 表明该类不是为继承而设计的。 您将所有构造函数设置为private,以便让类控制其实例化。

换句话说,使用final 控制继承,而使用private 构造函数控制实例化。

请注意,声明构造函数 private 只会禁用来自外部的继承。在类内部,您仍然可以使用命名或匿名派生类继承它。

当您创建private 类的所有构造函数时,您需要一个公开的static 方法以使该类可用。一种常见的static 方法是工厂方法:您可以让您的类的用户通过公共静态方法间接调用私有构造函数。

【讨论】:

【参考方案3】:

据我所知,private 构造函数的一般用途是确保对象构造是通过其他方式完成的,即静态方法。例如:

public class Something 

    private Something()  

    public static Something createSomething() 
        Something ret = new Something();
        // configure ret in some specific way
        return ret;
    


因此,私有构造函数限制了类的实例化方式(而不是扩展方式)。

另一方面,将类标记为final 用于明确表示类不能扩展。如何实例化完全是另一回事。

因此,虽然我不是 100% 是否有办法扩展具有所有私有构造函数的类 - 问题是您为什么要这样做?拥有一个私有构造函数并将一个类标记为 final 有两个不同的目的。

【讨论】:

是的,这或多或少是 Singleton 正在做的事情——添加一个标志,它是否已经实例化了自己。如果有办法绕过它,我可以显式调用 java.lang.Runtime 的一些非静态方法。但真好。 ..而且,Eclipse 消息具有误导性。正如我在 Q 中提到的那样。 跟踪。在 Eclipse 消息中,编译器可能没有考虑到您将所有构造函数标记为私有的事实 - 它只是说您尝试调用的任何一个都不起作用(因此“调用另一个”)。另外,总的来说,我仍然不明白您要解决什么问题。这里的几篇文章已经清楚地回答了最终类和私有构造函数之间的区别,但我不知道您是否已经阐明了您要解决的高级问题(设计模式)(可能是另一篇文章的主题)。

以上是关于Java——私有构造函数 vs final 等等的主要内容,如果未能解决你的问题,请参考以下文章

Java-Final 类与私有构造函数:java.util.Arrays 和 java.lang.Math 之间的区别

具有私有构造函数和析构函数的类对象的向量?

Java面试金典

java中私有构造函数的作用

特征可以具有具有私有和受保护可见性的属性和方法吗?特质可以有构造函数、析构函数和类常量吗?

《面向对象程序设计》高手进~~~~~~~~~~~~!!