2016-02-19 120 views
3

我有一個單例:Guice。注入構造

public class MySingleton{ 
    public static getInstance(){//typical singleton getInstance 
    ... 
    } 

    //fields 
    private static volatile instance; 
    @Inject 
    private AnotherClassInstanceThatIWantToInjectHere anotherClassInst_BlaBla; 
    private MySingleton(){ 
    ... 
    anotherClassInst_BlaBla.doSmth();//NullPointerException happens! 
    ... 
    } 
} 

這是什麼NPE的原因是什麼?它是因爲它是構造函數還是因爲它是單例而發生的?

回答

2

當調用MySingleton的構造函數時,instance爲null。 Guice在有任何東西注入之前必須構造MySingleton的實例。

吉斯有單身的概念:要麼你在單身範圍類綁定你的模塊中,或者您註釋類爲@Singleton。然後你只需注入像往常一樣:

@Singleton 
public class MySingleton { 
    private AnotherClassInstanceThatIWantToInjectHere anotherClassInst_BlaBla; 

    @Inject public MySingleton(AnotherClassInstanceThatIWantToInjectHere anotherClassInst_BlaBla) { 
    this.anotherClassInst_BlaBla = anotherClassInst_BlaBla; 
    anotherClassInst_BlaBla.doSmth(); 
    } 
} 
+0

好的,但是這意味着什麼?我無法訪問構造函數中的注入字段? –

+0

@IvanZelenskyy正確。 –

+0

謝謝! ~~~~ –

1

anotherClassInst_BlaBla在這種情況下一個實例變量,我想這就是爲什麼你選擇setter注入。由於它是一個實例變量,並且setter注入需要一個實例來設置此變量,所以需要創建/構造MySingleton類的一個實例以使用anotherClassInst_BlaBla。

不久之後,您應該在調用構造函數MySingleton()之後調用doSmth()方法,因爲setter注入發生在構造實例之後。

+0

不,這不起作用。我不知道爲什麼,但是當我從構造函數移動到另一個(init())方法時,我仍然擁有NPE。 –

+0

如果你使用[初始化塊](http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html),它仍會導致NPE,因爲初始化塊發生在構造函數之前。您可以使用@IvanZelenskyy建議的構造函數注入方法,或者通過容器注入它並添加[PostConstructor](http://docs.oracle.com/javaee/5/api/javax/annotation/PostConstruct.html)方法來調用doSmith () 方法。但一個問題是,理想的是,無論是哪種方式,你的單身人士將不再是單身人士,因爲它具有公共構造。任何人都可以創建一個MySingleton類的實例。 – Bilguun

+0

我使用@ AndyTurner的答案,它的工作原理。單身註釋並注入構造函數。 –