【问题描述】:

我知道最终类(不能继承类)和私有构造函数(不能创建类的实例)之间的区别。但是为什么Java的类ArraysMath都有私有构造函数,但是Math是final类而Arrays是不是?

有什么区别?不是两个实用程序类吗?

谢谢

【问题讨论】:

  • 看起来Arrays 的作者只是忘记了final类。它的构造函数仍然是 private (并用 Suppresses default constructor, 确保不可实例化。 注释)并且没有创建 Arrays 的实例(没有反射,当然)而其余的 public 方法是 static,因此它也是一个“实用程序”类。语义上 MathArrays 都是“实用程序”。与 C# 相比,Java 缺少 static 类,如果 Java 在开始时有这样一种类而不需要 finalize 一个类并放置一个类可能会很好私有构造函数。
  • 好问题。我唯一的猜测是他们忘记了。 (java.util.Objects 也被标记为 final 并且构造函数是 private。私有构造函数抛出 AssertionError 带有消息“没有适合您的 java.util.Objects 实例!” :-) )

标签: java constructor private final


【解答1】:

当类具有私有构造函数但不是最终类时,您可以在同一个类文件中定义具有公共构造函数并且可以实例化的内部类。但是您不能在该初始类文件之外定义任何子类。 例如,这将编译:

public class Animal {
  public void say() {
    System.out.printLn("Animal says:");
  }
  private Animal() {}

  public static class Cat extends Animal {
    public Cat() {super();}
    @Override public void say() {
      super.say();
      System.out.printLn("Meow");
    }
  }
}

但是,这(在另一个文件中定义)不会:

public class Dog extends Animal {
  public Dog() {super();} // compilation error here: The constructor Animal() is not visible
  @Override public void say() {
    super.say();
    System.out.printLn("Wuf");
  }
}

此技术允许您定义类层次结构,您可以完全控制哪些类型可以扩展您的类(因为所有这些子类型都必须在同一个类文件中枚举)。

也就是说,由于上述原因,java.util.Arrays 没有被定义为非最终的 - 它可能只是实现者的疏忽,与所有匹配无关,因此它没有修复迄今为止。

【问题讨论】: