2012-01-24 37 views
7

Tôi có hai lớp:Rắc rối với trường tĩnh và singleton

public class Singleton{ 
    private Singleton(){...} 

    private static class InstanceHolder{ 
     private static final Singleton instance=new Singleton(); 
    } 

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

public class Someclass{ 
    private static final Singleton singleton=Singleton.getInstance(); 

    public static Singleton getSingleton(){ 
     return singleton; 
    } 
} 

Vấn đề

Nếu ở đâu đó (trên thực tế, trong một constructor singleton-class) Tôi sử dụng một cái gì đó như thế này:

private final Singleton singleton=Someclass.getSingleton(); 

my singleton luôn rỗng

Câu hỏi Tại sao?

+0

Ứng dụng có hoạt động nếu bạn làm điều đó bên ngoài nhà xây dựng không? – Vadim

Trả lời

8

Ví dụ của bạn hoạt động tốt, do đó nó không đầy đủ.

Có lẽ trong ứng dụng thực tế của bạn, bạn có một chu kỳ dependecy giữa các lớp của bạn, do đó getSingleton() được gọi trước khi khởi tạo của Someclass được hoàn thành, một cái gì đó như sau, nhưng với nhiều lớp tham gia:

public class Foo { 
    private static Foo INSTANCE = new Foo(); // Prints null 
    private static String s = "foo"; 

    public Foo() { 
     System.out.println(s); 
    } 
} 

Đó là đặc biệt có khả năng nếu bạn có nhiều đơn độc lập phụ thuộc nhau được thực hiện theo cách này. Cố gắng tìm và loại bỏ các chu kỳ này.

Ngoài ra, có lẽ tốt hơn nên sử dụng một số loại mẫu DI hoặc Service Locator thay vì thực hiện hành vi đơn giản theo cách thủ công.

1

Bạn nên tạo bản sao đơn lẻ trong lần gọi đầu tiên thành getInstance() thay vì tĩnh. Điều này sẽ làm việc bất kể chu kỳ phụ thuộc.

public class Singleton { 
    private static Singleton instance = null; 

    private Singleton(){...} 

    public static Singleton getInstance() { 
    if(instance == null) { 
     instance = new Singleton(); 
    } 
    return instance; 
    } 
} 
+0

Trong tác giả lớp 'Singleton' đã làm như vậy bằng cách sử dụng thành ngữ chủ sở hữu tĩnh. Vấn đề là ở các lớp khác. – axtavt

+0

Nhưng cá thể được tạo tĩnh trong bài gốc. Trong đề nghị của tôi nó không phải là. Điều này đảm bảo cá thể được tạo sau tất cả các khởi tạo tĩnh. (Trừ khi có 'riêng Singleton s = Singleton.getInstance()' ở đâu đó. – tobiasbayer

+1

Tôi nghĩ tốt hơn là làm cho getInstance được đồng bộ hóa. –

Các vấn đề liên quan