Java类怎么可能没有参数构造函数?

Java类怎么可能没有参数构造函数?,java,constructor,Java,Constructor,Oracle Java教程网站上的这一段让我感到困惑: 所有类都至少有一个 构造器。如果一个类没有 显式声明任何 编译器自动提供 没有参数构造函数,称为 默认构造函数。此默认值 构造函数调用类父类的 没有参数构造函数或对象 构造函数,如果该类没有其他 父母亲如果家长没有 构造函数(对象确实有一个), 编译器将拒绝该程序 如果所有对象都直接或间接地从对象继承,那么如何可能引发所说的编译器拒绝?这与构造函数是私有的有关吗?对象的直接超类必须有一个受保护的构造函数或公共构造函数(或者根本没有构造函数,

Oracle Java教程网站上的这一段让我感到困惑:

所有类都至少有一个 构造器。如果一个类没有 显式声明任何 编译器自动提供 没有参数构造函数,称为 默认构造函数。此默认值 构造函数调用类父类的 没有参数构造函数或对象 构造函数,如果该类没有其他 父母亲如果家长没有 构造函数(对象确实有一个), 编译器将拒绝该程序


如果所有对象都直接或间接地从对象继承,那么如何可能引发所说的编译器拒绝?这与构造函数是私有的有关吗?

对象的直接超类必须有一个受保护的构造函数或公共构造函数(或者根本没有构造函数,在这种情况下将创建一个构造函数)。所以,如果我创建了一个只使用私有构造函数扩展对象的类,那么就没有任何东西能够扩展我的类。

如果你有一个子类的子类

class A 
{
    A(int i) {..}
}

class B extends A 
{
}

这里插入到
B
中的默认构造函数将尝试调用A的无参数构造函数(不存在),因为它只有一个构造函数接受一个参数,这意味着如果您从一行使默认无参数构造函数私有(例如,它不存在)的类继承,子类必须声明与其父类的替代构造函数一致的构造函数

例如,不允许以下Bar声明:

public class Foo {
  private Foo() {  } // or this doesn't even exist
  public Foo(int i) {
  }
}
public class Bar extends Foo {
}

要理解的关键是,如果类还没有构造函数,则只会自动生成无参数构造函数


因此,很容易创建一个没有无参数构造函数的类。

是。私有构造函数是一种特殊的实例构造函数。它通常用于仅包含静态成员的类中。如果一个类有一个或多个私有构造函数而没有公共构造函数,则不允许其他类(嵌套类除外)创建该类的实例

私有构造函数的声明阻止自动生成默认构造函数

编辑:

在另一个类中定义的类 被称为嵌套类。像其他 类的成员,嵌套类可以 是否声明为静态。A. 非静态嵌套类称为 内部阶级内部事件的实例 类只能存在于 它的封闭类和 有权访问其封闭类的 成员,即使他们被宣布 私人

如果所有对象都直接或间接地从对象继承,那么如何可能引发所说的编译器拒绝

我认为你误解的基础是你认为构造函数是继承的。事实上,构造函数不是在Java中继承的。请考虑下面的例子:

public class A {
    public A(int i) { super(); ... }
}

public class B extends A {
    public B() { super(); ... }
}
A

  • 不从
    对象
    继承任何构造函数
  • 未显式声明无参数构造函数(即
    public a(){…}
    ),以及
  • 没有默认构造函数(因为它声明了另一个构造函数)
因此,它只有一个构造函数:
public A(int)

类中对
super()
的调用试图使用
a
中不存在的无参数构造函数,并给出编译错误。要解决此问题,您需要将
B
构造函数更改为使用
A(int)
构造函数,或者在
A
中声明一个显式无参数构造函数

(顺便说一句,构造函数没有必要像我所做的那样显式调用超类构造函数。但是很多人认为包含显式调用是一种很好的方式。如果不包含它,Java编译器会插入对超类no args构造函数的隐式调用……如果没有gs构造函数不存在或对子类不可见。)

这与构造函数是私有的有关吗


不直接。但是,声明构造函数私有将防止从子类调用该构造函数。

思考此问题的最简单方法如下:

  • Java为您创建的任何类提供了非args构造函数作为默认构造函数

  • 当您创建带有参数的自定义构造函数时,Java会说“嘿,这个类有一个自定义构造函数,所以我不想麻烦创建/提供默认的非参数构造函数!

  • 因此,现在您的类没有默认的非参数构造函数

  • 这意味着在基于类创建子类时,需要显式调用所创建的基于参数的自定义构造函数


  • 让我在前面提到的一个更有趣的例子之后再加上一个例子,默认/无参数构造函数是不可行的,在这个意义上,除非显式声明,否则编译器不能假定它,但它与子类化无关。这是一个类有一个
    final
    字段,该字段要求构造函数初始化将其具体化。例如:

    class Foo extends Object {
        private final Object o;
    
        public Foo(Object o){
           this.o = o;
        }
    }
    

    在这里很容易看出,Foo对象的实例化需要初始化最后一个字段
    o
    ,因此任何直接调用
    Foo()
    ,无论是否调用,都注定要失败……让我强调一下,超类(
    对象
    )中的无参数构造函数存在并可公开访问,但在
    Foo

    中存在最终字段(
    o
    )会将其停用,因为您没有在中重写无参数构造函数,它不应该从对象继承吗?不,构造函数不是继承的,如果两个类都是继承的,那么包访问构造函数也是允许的