为什么构造函数在Java中不能是最终的,静态的或抽象的?
例如,您可以向我解释为什么这无效吗?
public class K {
abstract public K() {
// ...
}
}
当将方法设置为final
时,它的意思是:“我不希望任何类重写它。”但是根据Java语言规范:
JLS 8.8-“构造函数声明不是成员。它们从不继承,因此不受隐藏或覆盖。”
[将方法设置为abstract
时,它的意思是:“此方法没有主体,应在子类中实现。”但是,当new
关键字被隐式调用时,构造函数将被隐式调用。被使用,所以它不会缺少身体。
[将方法设置为static
时,它的意思是:“此方法属于类,而不是特定的对象。”但是隐式调用了构造函数以初始化对象,因此具有静态构造函数。
首先查看最终公开K(){
问题实际上是为什么要让构造函数成为static or abstract or final
。
构造函数不是继承的,所以不能被覆盖,所以有什么用具有最终的构造函数
当类的实例为创建后,它可以访问该类的实例字段。会是什么使用静态构造函数。
构造函数不能被覆盖,因此您将如何处理抽象构造函数。
Java构造函数是implicitly最终的,其语义的静态/非静态方面是implicit 1,对于Java构造函数来说,抽象是无意义 。
这意味着final
和static
修饰符将是多余的,并且abstract
关键字根本没有任何意义。
自然,Java设计者在任何时候都没有看到在构造函数上允许冗余和/或无意义的访问修饰符……因此Java语法不允许使用这些修饰符。
另外:很遗憾他们没有对接口方法进行相同的设计调用,在这些接口方法中public
和abstract
修饰符也是多余的,但无论如何还是允许的。也许有一些(古老的)历史原因。但是无论哪种方式,如果不(可能)使数百万个现有的Java程序无法编译,就无法修复它。
1-实际上,构造函数混合使用静态和非静态语义。您不能在实例上“调用”构造函数,并且它们不能被继承或覆盖。这类似于静态方法的工作方式。另一方面,构造函数的主体可以引用this
,并调用实例方法...就像实例方法一样。然后是构造函数链接,这对于构造函数是唯一的。但是真正的要点是这些语义是固定的,没有意义允许多余且可能令人困惑的static
修饰符。
[public
构造函数:可以在任何地方创建对象。
默认构造函数:只能在同一程序包中创建对象。
[protected
构造函数:仅当包是子类时,才能由包外部的类创建对象。
[private
构造函数:只能在类内部创建对象(例如,在实现单例时)。
static
,final
和abstract
关键字对构造函数没有意义,因为:
[static
成员属于一个类,但是创建对象需要构造函数。
abstract
类是部分实现的类,其中包含要在子类中实现的抽象方法。
final
限制修改:变量变为常量,方法不能被覆盖,并且类不能被继承。
Final:因为您仍然无法覆盖/扩展构造函数。您可以扩展一个类(以防止最终完成)或覆盖一个方法(以防止最终完成),但对于构造函数而言,则没有类似的东西。
Static:如果您查看执行,则构造函数不是静态的(它可以访问实例字段),如果您查看调用方,则它是(某种)静态的(您在没有实例的情况下调用它)。很难想象一个构造函数是完全静态的还是不是静态的,并且在这两件事之间没有语义上的分离,所以用修饰符来区分它们是没有意义的。
Abstract:抽象仅在存在覆盖/扩展的情况下才有意义,因此适用与“ final”相同的论点]]
绝对不能将构造函数声明为final。您的编译器将始终给出类型为“不允许使用修饰符final”的错误最终,当应用于方法时,意味着该方法不能在子类中重写。构造函数不是普通的方法。 (适用不同的规则)此外,构造函数永远不会被继承。因此,在最终声明中没有任何意义。
[JLS section 8提及此。
为什么构造函数不能是静态的,而final在以上答案中得到了很好的定义。