Java 构造方法私有化与单例模式

转载自:http://blog.csdn.net/wei_zhi/article/details/52832334

先看一个程序:


class Singleton { // 定义一个类
    public void print() {
        System.out.println("Hello World");
    }
}


public class Test {
    public static void main(String args[]) {
        Singleton inst = null; // 声明对象
        inst = new Singleton(); // 实例化对象
        inst.print(); // 调用方法
    }
}


上面的Singleton类里是存在构造方法的(如果一个类中没有明确的定义一个构造方法的话,会自动生成一个无参默认的构造方法),现在把构造方法修改一下:


class Singleton { // 定义一个类
    private Singleton() {
    } // 构造方法私有化


    public void print() {
        System.out.println("Hello World");
    }
}


我们知道,构造方法被私有化,就无法在类外部实例化Singleton对象。


那么,此时,如何在Test类里面得到Singleton类的实例化对象并且调用print()方法?


首先,这个类的构造方法被私有化,只能被本类所调用,所以可以在本类中产生本类的实例化对象:


class Singleton { // 定义一个类


    Singleton instance = new Singleton();//在本类中产生本类的实例化对象


    private Singleton() {
    } // 构造方法私有化


    public void print() {
        System.out.println("Hello World ");
    }
}


我们知道,此时instance 属性只是一个普通属性,必须在类实例化对象后再可以使用,要想不需要实例化对象直接使用,可以使用static声明:


class Singleton { // 定义一个类
    static Singleton instance = new Singleton();


    private Singleton() {
    } // 构造方法私有化


    public void print() {
        System.out.println("Hello World");
    }
}


public class Test {
    public static void main(String args[]) {
        Singleton inst = null; // 声明对象
        inst = Singleton.instance; // 实例化对象
        inst.print(); // 调用方法
    }
}


但是,我们知道,类中的全部属性都应该封装,以上的instance属性也应该封装:


private static Singleton instance = new Singleton();
1
而封装之后要想取得属性。要编写getter方法,不过这里的getter方法应该也由类名称直接调用,定义为static型,getInstance()方法:


class Singleton { // 定义一个类
    private static Singleton instance = new Singleton();


    private Singleton() {
    } // 构造方法私有化


    public void print() {
        System.out.println("Hello World ");
    }


    public static Singleton getInstance() {
        return instance;
    }
}


public class Test {
    public static void main(String args[]) {
        Singleton inst = null; // 声明对象
        inst = Singleton.getInstance(); // 实例化对象
        inst.print(); // 调用方法
    }
}


为什么这么做呢?此时程序之中的instance属性,属于static,那么,不管有多少个Singleton类的对象,都共同拥有同一个instance属性。


我们再来看,若getInstance()方法修改如下:


    public static Singleton getInstance() {
        instance = new Singleton();
        return instance;
    }
此时,发现,每调用一次getInstance()方法,就会实例化一个Singleton对象,这样的话,实例化对象就不是唯一的了,所以,这种情况不能让它出现,怎么办?可以在定义instance属性的时候增加一个final关键字:


 private static final Singleton INSTANCE = new Singleton() ;
于是,最后的代码就变成了这样:


class Singleton { // 定义一个类
    private static final Singleton INSTANCE = new Singleton();


    private Singleton() {
    } // 构造方法私有化


    public void print() {
        System.out.println("Hello World .");
    }


    public static Singleton getInstance() {
        return INSTANCE;
    }
}


public class Test {
    public static void main(String args[]) {
        Singleton inst = null; // 声明对象
        inst = Singleton.getInstance(); // 实例化对象
        inst.print(); // 调用方法
    }
}


这样的设计在设计模式上讲就称为单例设计模式(Singleton)。


单例设计模式的类型:


(1)饿汉式单例模式:当类装载的时候就会创建类的实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要再判断。上面的程序就属于饿汉式单例模式,


(2)懒汉式单例类:每次获取实例都会进行判断,看是否需要创建实例,如果一直没有人使用的话,那就不会创建实例。代码如下:


class Singleton { // 定义一个类
    private static Singleton instance;


    private Singleton() {
    } // 构造方法私有化


    public void print() {
        System.out.println("Hello World .");
    }


    public static Singleton getInstance() {
        if (instance == null) { // 没有实例化
            instance = new Singleton(); // 实例化
        }
        return instance;
    }
}


小结:单例模式的特点?


(1)构造方法被私有化(private); 
(2)只能够通过getInstance()方法取得Singleton类的实例化对象,这样不管外部如何操作,最终也只有一个实例化对象; 
(3)在单例设计模式之中,一定会存在一个static方法,用于取得本类的实例化对象。

猜你喜欢

转载自blog.csdn.net/keep12moving/article/details/79198232