1. 程式人生 > >Don't rush and never settle. If it's meant to be, it will be.

Don't rush and never settle. If it's meant to be, it will be.

主體程式碼

class MyObject{
    //這是具體的實現方法
}
class MyThread extends Thread{
    @Override
    public void run(){
        System.out.println(Thread.currentThread()+" "+MyObject.getInstance().hashCode());
    }
}
public class SingleMain{

    public static void main(String[]args){
        MyThread thread1=new
MyThread(); MyThread thread2=new MyThread(); MyThread thread3=new MyThread(); thread1.start(); thread2.start(); thread3.start(); } }

使用靜態內部類實現

class MyObject{
    private static class MyObjectHandler{
        private static MyObject myObject=new MyObject();
    }
    private
MyObject(){} public static MyObject getInstance(){ return MyObjectHandler.myObject; } }

執行結果:
這裡寫圖片描述

使用static程式碼塊實現

class MyObject{
    public static MyObject myobject=null;
    private MyObject(){}
    static {
        myobject=new MyObject();
    }
    public static MyObject getInstance
(){ return myobject; } }

執行結果:
這裡寫圖片描述

使用enum列舉型別實現

什麼是列舉型別

下面的程式碼定義了3種顏色,包括顏色的編號和名稱,
在列舉類中構造方法是私有的,不允許外界呼叫,在使用時自動呼叫,這符合單例模式的要求。

 enum Color{
    RED("red",0),ORANGE("orange",1),YELLOW("yellow",2);
    private String name;
    private int num;
    private Color(String name,int num){
        this.name=name;
        this.num=num;
    }
    public String getName(){
        return this.name;
    }
    public int getNum(){
        return this.num;
    }
}
public class MyEnum{
    public static void main(String[] args){
        System.out.println("顏色名稱"+Color.RED.getName()+" 顏色編號"+Color.RED.getNum());
    }
}

用列舉類實現單例模式

class MyObject{

}
class AssistantObject{

    public enum MyEnumClass{
        RealObject(new MyObject());
        private MyObject myobject;
        private MyEnumClass(MyObject myobject){
            this.myobject=myobject;
        }
        public  MyObject getInstance(){
            return this.myobject;
        }
    }
    public static MyObject getInstance(){
        return MyEnumClass.RealObject.getInstance();
    }
}

執行結果:
這裡寫圖片描述

為什麼列舉型別可以實現單例模式

列舉型別

列舉型別就是一些具有相同特性的類常量

java中類的定義使用class,列舉類的定義使用enum。在Java的位元組碼結構中,其實並沒有列舉型別,列舉型別只是一個語法糖,在編譯完成後被編譯成一個普通的類。這個類繼承java.lang.Enum,並被final關鍵字修飾。

public enum Fruit {
    APPLE,ORINGE
}

使用jad對編譯後的class檔案進行反編譯後得到:


public final class Fruit extends Enum
{

    public static Fruit[] values()
    {
        return (Fruit[])$VALUES.clone();
    }

    public static Fruit valueOf(String s)
    {
        return (Fruit)Enum.valueOf(Fruit, s);
    }

    private Fruit(String s, int i)
    {
        super(s, i);
    }
    //列舉型別常量
    public static final Fruit APPLE;
    public static final Fruit ORANGE;
    private static final Fruit $VALUES[];//使用陣列進行維護

    static
    {
        APPLE = new Fruit("APPLE", 0);
        ORANGE = new Fruit("ORANGE", 1);
        $VALUES = (new Fruit[] {
            APPLE, ORANGE
        });
    }
}

從這裡可以看出,使用了列舉型別就相當於是使用static程式碼塊實現。