2017-10-08 28 views
-1

//問題:將一個類的實例限制爲一個。如何限制類實例化爲一個?

class Runtime{ 
    private static Runtime r; 
    private Runtime(){ 
    System.out.println("In Runtime class."); 
    } 
    static{ 
    r=new Runtime(); 
    } 
    static Runtime getRuntime(){ 
    Runtime r=new Runtime(); 
    return r; 
    } 
} 

class TestRuntime{ 
    public static void main(String[] args) { 
     Runtime r1; 
     r1=Runtime.getRuntime(); 
    } 
} 

我想了解一下這個代碼實際上做,以及它是如何限制的對象創建。 可能的其他解決方案是什麼?優選地,以這種代碼解決問題的方式。

+0

這並不是,它會在每次調用getRuntime時創建一個新實例 – UnholySheep

+1

您似乎在尋找的是「單例模式」,例如:[Wikipedia article](https:// en。 wikipedia.org/wiki/Singleton_pattern)以獲得更多信息(以及一個非常簡單的例子) – UnholySheep

+0

我發現了這篇關於單例模式的文章:https://www.javaworld.com/article/2073352/core-java/simply-singleton。 html – esprittn

回答

0

你已經發布的代碼似乎是錯誤的。這不是一個單身人士課程。每次調用getRuntime()時,都會創建一個新實例。相反,在getRuntime方法中,應該直接返回'r'(在靜態塊中初始化)。

如果您正在尋找Singleton模式,看看下面的實現。所有的 https://en.wikipedia.org/wiki/Singleton_pattern#Lazy_initialization

0

首先你問是一個很常見的問題。很常見,它被稱爲「單身模式」,你可以搜索它,你會發現更多的信息。至於你的代碼,它幾乎是好的。您getRuntime()方法更改爲這一點,你會被罰款(從getRuntime()刪除線r1=Runtime.getRuntime();

static Runtime getRuntime(){ 
     return r; 
    } 

現在有到instanciating辛格爾頓2種主要的方法 - 急切和懶惰。

  1. Eager意味着您的單例將在您的應用程序啓動時立即執行。這就是你所做的。大「親」是它海峽前進和簡單。如果你的Singleton有很大的佔用空間並且需要很長的時間來初始化,那麼你的應用程序會在「需要」之前「浪費」內存,並且需要更長的時間才能初始化。
  2. 懶意味着,只有當它實際上是要求首次您辛格爾頓被創建。 「優點」:您的Singleton dos不會延遲您的應用程序啓動時間並節省內存。 「Con」:執行過程複雜而且嚴重。搜索網頁查看原因。
    但是,如果你使用一些框架(例如Spring)來管理所有的實例,那麼你所需要做的就是說一個特定的類必須是一個單例,並且懶惰地執行,所以沒有複雜性

    基本上,建議是,如果你可以負擔得起你的辛格爾頓急切(即該方法的缺點是可以容忍的),那就用這種方法。如果此方法由於某些原因而不被接受,請使用Lazy instanciation
0

在JVM的引擎下,您無法真正「阻止」創建一個類的多個實例。另一方面,你有時想在代碼中的任何地方使用同一個對象是很常見的,因爲只有一個實例是沒有意義的。所以人們提出了「單身人士」的想法。

在Java中,單身由把戲,利用「靜態」修飾符的實現。通過將某些東西標記爲「靜態」,您告訴編譯器您希望讓該類的所有實例共享一個副本。這使得每個類的字段而不是每個實例。所以除非你自定義類加載器或類似的東西,否則這意味着你在整個JVM中都有一個單獨的拷貝。

此外,你需要一個構造函數私有,讓其他的代碼不能只是調用構造函數來創建另一個實例。

但是,您應該記住,這只是編譯器強制執行的一個「cosmetical」限制。認爲它是一種很好的編程方式。例如,仍然可以通過反射創建其他對象。

0

一個非常基本實現真正的辛格爾頓是這樣的:

public class Runtime { 

    // a single(ton) instance to limit the instantiation to 1 
    private static Runtime runtimeInstance; 

    // a private constructor, not accessable from outside this class! 
    private Runtime() { 
     System.out.println("First creation of a Runtime instance."); 
    } 

    // the method that actually provides a single instance to callers 
    public static Runtime getInstance() { 
     // if the instance is not yet instanciated 
     if (runtimeInstance == null) { 
      // instanciate it with the private constructor 
      runtimeInstance = new Runtime(); 
     } 
     // return the instance 
     return runtimeInstance; 
    } 
} 

因此您可以通過

Runtime runtime = Runtime.getInstance(); 

它總是給你一個實例調用的對象。

+1

絕對是一個錯誤的例子。有幾個線程可以同時檢查條件「if(runtimeInstance == null)」,而它仍然是空的,然後每個線程都會創建一個新的實例。這是一個經典的例子,如何不寫Singleton –

+0

我應該指出,這個例子只是爲了瞭解Singleton的基本知識,因爲這個問題根本不是關於不同的線程。我爲你的評論投票,因爲你是對的,但在這個問題的背景下,你的建議可能會有點太多的開銷... – deHaar

+0

我明白你的觀點,但不同意。 Singleton基本上意味着多線程環境,但我認爲這是辯論的一個公平點。在任何情況下,你都會非常喜歡加爾蘭特和大部分人對你的答案表示讚賞。謝謝。 –