2013-03-26 40 views
6

Tôi có singleton này tôi đang cố gắng để sử dụng, nhưng getInstance dường như có thể trở về null:Java Singleton.getInstance() trả về null?

class Singleton { 
    public static final String K_LEVEL = "level"; 
    static Singleton instance = new Singleton(); 
    private int level; 

    static Singleton getInstance() { 
     return instance; 
    } 

    int getLevel() { 
     return level; 
    } 

    void incrementLevel() { 
     System.out.println("LEVEL INCREASED TO " + ++level); 
    } 

    void addToLevel(int x) { 
     for(int i=0;i<x;i++) 
      incrementLevel(); 
    } 

} 

class A { 
    public static void main(String[] args) { 
     Singleton s = Singleton.getInstance(); 
     Integer i = Integer.getInteger(Singleton.K_LEVEL); 
     s.addToLevel(i); 
    } 
} 

tôi nghe thực hiện độc thân trong Java là rất khó khăn và dễ bị điều kiện chủng tộc. Mẫu đơn của tôi có bị lỗi không? Gần đây tôi đã thay đổi mã của tôi để trông như thế này, và bây giờ getInstance trả về null đôi khi. Tại sao?

$ java A -Dlevel=1 
Exception in thread "main" java.lang.NullPointerException 
    at A.main(A.java:29) 
+1

'System.out.println (i);' ngay trước 's.addToLevel (i);' print là gì? – jlordo

Trả lời

2

Không có gì sai với Singleton của bạn. Không có vấn đề đồng thời vì đây không phải là mã đa luồng.

Bạn đang suy nghĩ s là không, nhưng thực sự là i không có giá trị.

Kể từ addToLevel mất một int như một tham số, các Integer i được autounboxed (ngầm chuyển đổi từ Integer để int), nhưng kể từ khi inull, NullPointerException bị ném. Tự động tạo hộp thoại ném NullPointerException khi giá trị được chuyển đổi là null.

Lý do Integer.getInteger(Singleton.K_LEVEL) trả lại null là vì bạn đã làm java A -Dlevel=1 thay vì java -Dlevel=1 A. Sau đó là cú pháp chính xác.

2

Đây không phải về mẫu đơn của bạn trông rất hợp với tôi. Đây là phương thức Integer.getInteger(Singleton.K_LEVEL); trả về giá trị rỗng. Tôi đặt cược thuộc tính hệ thống "level" chưa được đặt và là null.

Từ nhận xét của tôi, bạn cần đặt -Dlevel=1trước lớp A trên dòng lệnh. Nếu bạn gỡ lỗi mã của bạn hoặc in ra các thuộc tính hệ thống, bạn sẽ thấy rằng nó là null.

Bạn nhận được NPE khi bạn cố gắng chuyển số null vào addToLevel(int x) và nó cố gắng tự động hủy chọn null thành int x.

Là một sang một bên, nếu lớp này được sử dụng bởi nhiều chủ đề, bạn nên cân nhắc sử dụng một lớp AtomicInteger bên trong lớp Singleton của bạn mà là reentrant.

+0

Không, tôi đặt nó bằng cách thực hiện điều này: 'java A -Dlevel = 1' – Dog

+1

' -D' phải là _before_ 'A' class @Dog. Tôi muốn gỡ lỗi mã của bạn hoặc in ra thuộc tính hệ thống để xác minh nó. – Gray

+1

Tôi đồng ý. @ Tại sao bạn không in tôi ngay trước khi gọi addToLevel để xác minh. –

1

java -Dlevel=1 A phải phù hợp với nhu cầu của bạn.

Từ doc, cú pháp là java [ options ] class [ argument ... ]-Dlevel=1 được coi là một tùy chọn (xem phần options).

0

static Singleton instance = new Singleton(); phải là cuối cùng để ngăn tình trạng cuộc đua.