学编程尤其是OOP,总是要问为什么。这是我的问题:为什么要这么干?为什么要私有化?为什么是私有化构造方法而不是其他东西?
首先,我直接解释,这样子定义一个工具类实际上是源于一种设计模式——单例模式,而这种设计模式自然有它的好处,所以我们才要这么写。
单例模式的好处?
转载:
对于系统中的某些类来说,只有一个实例很重要。
例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。
如何保证一个类只有一个实例并且这个实例易于被访问呢?定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象。一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的模式动机。
如何编写单例模式?
已经说了,就是用private修饰构造方法,将其私有化,这样我们就不能在外部实例化这个对象。例如下面这段代码就会会报错。
public class Private2 {
public static void main(String[] args) {
Singleton s = null; // 这一步是声明对象,并不会报错
s = new Singleton(); // 这一步是实例化对象,调用了私有化的构造方法,会报错
// 上面两行代码就相当于Singleton s = new Singleton();
s.prit();
}
}
class Singleton {
// 单例模式(Singleton Pattern)是Java 中最简单的设计模式之一
private Singleton() {
// 构造方法私有化
// 此时这个构造方法只能再本类中可见,所以上面实例化对象的时候会报错
}
public void prit() {
System.out.println("javajava");
}
}
为什么不能实例化?(这个问题实际上也解释了为什么私有化的是构造方法而不是其它)
首先我们需要知道实例化对象的步骤,代码上看是new出来的,底层是因为实例化对象首先需要初始化对象,而对象的初始化是通过编译器调用构造器(构造方法)来实现的,这样才能够为其分配内存。那么现在将构造方法私有化之后,外部就无法调用,自然也就无法初始化,也就无法实例化,你自然就new不出来了。
如果我们想在类的外部使用类的对象,只能在类的内部实例化一个类的对象,然后调用这个对象。
public class Private2 {
public static void main(String[] args) {
Singleton3 s1 = null;//声明对象
s1 = Singleton3.getSingleton3();//用类名称.对象名,来给s1赋值
s1.fun();
}
}
class Singleton3 {
private static Singleton3 s = new Singleton3(); // 实例化静态对象s
public static Singleton3 getSingleton3() {
// Singleton3就是方法的返回类型,表示该方法返回一个 Singleton3 类的对象。
return s;
}
// 当然也可以像下面这种形式一样直接返回一个new的对象
// public static Singleton3 getSingleton3() {
// // Singleton3就是方法的返回类型,表示该方法返回一个 Singleton3 类的对象。
// return new Singleton3();
// }
private Singleton3() {
System.out.println("JAVAJAVA");
}
public void fun() {
System.out.println("javajava");
}
}
因此无论你在外部创建多少个类的对象也只能是对内部对象的引用,外部定义的类的对象根本没有实例化的能力。这就是单例设计模式,从头至尾只有一个(内部的)对象的实例。
注意:如果我们不提供构造方法,JVM会默认提供一个空参的public构造器,如果使用默认的构造方法,那么开发人员仍然可以手动创建对象,而工具类的目的就是让你用的方便,不让你new对象,而是直接调用方法。
以上就是我结合单例模式对于私有化构造方法的深入理解,如有不足,望指正!