一,構造方法私有化:
即對構造方法加上private關鍵詞。
如:
class Singleton{ private Singleton(){ // 將構造方法進行了封裝,私有化 } };
但是由於私有化的方法和屬性只能在本類中看到和訪問,其他方法中是看不到的!
所以對於以下做法。
class Singleton{ private Singleton(){ // 將構造方法進行了封裝,私有化 } public void print(){ System.out.println("Hello World!!!") ; } }; public class SingletonDemo02{ public static void main(String args[]){ Singleton s1 = null ; // 聲明對象 s1 = new Singleton() ; // 錯誤,無法實例化對象 } };
運行結果:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The constructor Singleton() is not visible
at methoud.ThisDemo06.main(ThisDemo06.java:13)
會出現錯誤,無法實例化對象。私有化的構造方法在其他類中是不可見的。
被構造方法私有化的Singleton類,不能在外部實例化。
既然不能在外部實例化,如果在類的內部實例化呢
class Singleton{ Singleton instance = new Singleton() ; // 在內部產生本類的實例化對象 private Singleton(){ // 將構造方法進行了封裝,私有化 } public void print(){ System.out.println("Hello World!!!") ; } }; public class SingletonDemo04{ public static void main(String args[]){ Singleton s1 = null ; // 聲明對象 } };
但是這里雖然在內部產生了實例化對象,卻沒有在外部使用,賦給s1.怎么辦?
一個類的構造方法私有化之后,只能從類的內部取得實例化對象。那么,要考慮的問題是,如何把內部生成的
instance 對象拿到外部來,這樣外部就可以直接實例化了。
正常情況下,instance屬性只能通過singleton類的實例化對象才可以進行調用。
如果沒有實例化對象的時候依然可以取得instance對象,則就需要將instance聲明成static訪問類型,因為使用static
聲明的變量,可以直接使用類名稱進行訪問。
class Singleton{ static Singleton instance = new Singleton() ; // 在內部產生本類的實例化對象 private Singleton(){ // 將構造方法進行了封裝,私有化 } public void print(){ System.out.println("Hello World!!!") ; } }; public class SingletonDemo04{ public static void main(String args[]){ Singleton s1 = null ; // 聲明對象 s1 = Singleton.instance ; // 通過類取得實例化對象 s1.print() ; // 調用方法 } };
運行結果:hello world!!!
這樣就通過聲明static,把內部產生的對象,通過類名調用,取出到外部,賦給s1。
正常情況下,這些屬性應該封裝才對,所以,以上代碼最好修改成以下形式。
class Singleton{ private static Singleton instance = new Singleton() ; // 在內部產生本類的實例化對象 public static Singleton getInstance(){ // 通過靜態方法取得instance對象 return instance ; } private Singleton(){ // 將構造方法進行了封裝,私有化 } public void print(){ System.out.println("Hello World!!!") ; } }; public class SingletonDemo05{ public static void main(String args[]){ Singleton s1 = null ; // 聲明對象 s1 = Singleton.getInstance() ; // 取得實例化對象 s1.print() ; // 調用方法 } };
二,程序的意義:
為什么要這樣做呢?
如果現在產生了三個對象。
class Singleton{ private static Singleton instance = new Singleton() ; // 在內部產生本類的實例化對象 public static Singleton getInstance(){ // 通過靜態方法取得instance對象 return instance ; } private Singleton(){ // 將構造方法進行了封裝,私有化 } public void print(){ System.out.println("Hello World!!!") ; } }; public class SingletonDemo05{ public static void main(String args[]){ Singleton s1 = null ; // 聲明對象 Singleton s2 = null ; // 聲明對象 Singleton s3 = null ; // 聲明對象 s1 = Singleton.getInstance() ; // 取得實例化對象 s2 = Singleton.getInstance() ; // 取得實例化對象 s3 = Singleton.getInstance() ; // 取得實例化對象 s1.print() ; // 調用方法 s2.print() ; // 調用方法 s3.print() ; // 調用方法 } };
不管外部聲明了多少個對象,但是最終結果都是通過getInstance()方法取得的實例化對象。也就是說,
此時s1,s2,s3實際上都使用了一個對象的引用:instance。
那么在設計模式上,稱為單例設計模式:singleton。
如果現在不希望一個類產生過多的對象的話,則必須采用單例設計模式,而且,在以后的java學習中,
在支持java的類庫中,大量采用了這種模式。
所謂的單態就是在入口處(也就是構造方法)限制了實例化操作。
三,一個現實中的例子:
在window中有一個回收站,除了桌面有回收站,每個硬盤都有回收站,實際上每個硬盤上的回收站和桌面的回收站是同一個,
也就是說,整個操作系統只有一個回收站實例,各個地方只是引用這個實例而已。
四,總結
單例設計模式核心就是將類的構造方法私有化,之后在類的內部產生實例化對象,並通過類名引用類的靜態方法(static)返回實例化對象的引用。