【问题标题】:Java Final class or private constructorJava Final 类或私有构造函数
【发布时间】:2020-03-22 21:00:32
【问题描述】:

当我们想要关闭一个类以继承时,我们使用 final 声明类,

final class Myclass {}

但是当我们将构造函数声明为私有时,效果是一样的,

class Myclass {
     private Myclass() {}
}

但真的一样吗?代码的优化或代码的可读性有什么区别吗?以及哪些类必须接近继承,

  1. 不可变类可能
  2. 类的每个方法和成员变量都声明为静态

但是对于第二个选项java.util.Arrays 没有用final 声明,即使Arrays 的所有方法都声明为static

【问题讨论】:

标签: java inheritance final private-constructor


【解决方案1】:

但是当我们声明 ctor 私有时,效果是一样的

不一定,考虑这个使用静态类的例子:

public class SOExample {
    private static class ClassWithPrivateConstructor {
        private ClassWithPrivateConstructor() {
            System.out.println("I have a private constructor");
        }
    }

    private static class ClassThatExtendsClassWithPrivateConstructor extends ClassWithPrivateConstructor {
    }

    public static void main(String[] args) {
        new ClassThatExtendsClassWithPrivateConstructor();
    }
}

这将打印“我有一个私有构造函数”。

但真的一样吗?代码优化或代码可读性有什么区别。以及哪些类必须接近继承,

当开发人员看到一个类是最终类时,他们就会明白作者的意图是不应该对其进行扩展。

当开发人员看到一个类有一个私有构造函数时,他们就明白该类不能被实例化。这通常是因为它要么是一个静态实用程序类,要么是一个单例。

但是对于第二个选项 java.util.Arrays 没有用 final 声明,即使 Arrays 的所有方法都声明为静态

这是一个很好的观察。我的猜测是它可能应该是但现在不能为了向后兼容而改变。

【讨论】:

  • 好答案。使用私有构造函数的另一个原因是静态工厂方法提供了实例化,例如 java.time 类上的of 方法。示例:LocalDate ld = LocalDate.of( 2020 , Month.JANUARY , 23 ) ;
  • final 课程从 1.00 开始就存在 - 这对 String 非常重要。
【解决方案2】:

我通常做的是创建类final构造函数private

  1. 它消除了关于类使用的歧义(强调它是一个实用程序类)
  2. 它使用户远离他们不应该做的事情(启动、扩展)。

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class HttpTool {}

也就是说,java.util.Arrays 没有任何问题。设计者以必要的最小值(私有构造函数)达到预期的效果(不可实例化)。

【讨论】:

  • 如果不使用 lombok,代码示例对大多数人来说会更清晰。
【解决方案3】:

如果你想创建一个不可变类或者只是一个由于某种原因不应该有子类的类,你应该将它声明为 final。在实用程序类中应该使用私有构造函数,这样可以阻止继承并确保无法创建类的实例。

【讨论】:

    猜你喜欢
    • 2013-09-02
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    • 2016-10-17
    • 2016-12-28
    • 2017-03-28
    • 2022-12-04
    • 1970-01-01
    相关资源
    最近更新 更多