Java最终类或私有构造函数

Java最终类或私有构造函数,java,inheritance,final,private-constructor,Java,Inheritance,Final,Private Constructor,当我们想要关闭一个类进行继承时,我们用final声明这个类 final class Myclass {} 但是当我们将构造函数声明为private时,效果是一样的 class Myclass { private Myclass() {} } 但它真的是一样的吗?代码的优化和可读性有什么不同吗?哪些类必须接近继承 可能是不可变类 声明类为静态的每个方法和成员变量 但是对于第二个选项,java.util.Arrays没有用final声明,即使Arrays的所有方法都声明为static如

当我们想要关闭一个类进行继承时,我们用final声明这个类

final class Myclass {}
但是当我们将构造函数声明为private时,效果是一样的

class Myclass {
     private Myclass() {}
}
但它真的是一样的吗?代码的优化和可读性有什么不同吗?哪些类必须接近继承

  • 可能是不可变类
  • 声明类为静态的每个方法和成员变量

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

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

    我通常做的是将类设置为final,并将构造函数设置为Private:

  • 它消除了类使用的模糊性(强调它是一个实用类)
  • 它让用户远离他们不应该做的事情(启动、扩展)
  • @NoArgsConstructor(access = AccessLevel.PRIVATE)
    public final class HttpTool {}
    
    也就是说,
    java.util.Arrays
    没有什么问题。设计者用必要的最小值(私有构造函数)实现所需的效果(非实例化)

    但是,当我们宣布它为私有时,效果也是一样的

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

    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();
        }
    }
    
    这将打印“我有一个私有构造函数”

    但它真的是一样的吗?代码的优化和可读性有什么不同吗。哪些类必须接近继承

    当开发人员看到一个类是final时,他们理解作者的意图是不应该扩展它

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

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


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

    您看到这个答案了吗:这是否回答了您的问题?在字节码中,您可以在没有可访问构造函数的情况下对类进行子类化,但除非基类是可序列化的,否则无法创建它的实例。使用私有构造函数的另一个原因是静态工厂方法提供实例化,例如java.time类上的方法的。示例:
    LocalDate ld=LocalDate.of(2020年1月23日)
    期末
    课程从1.00开始就有了-这对
    字符串
    非常重要。谢谢@TomHawtin tackline,我根据您的反馈更新了答案。如果不使用lombok,代码示例对大多数人来说都会更清晰。