簡體   English   中英

Guice注入空指針

[英]Guice injection null pointer

我們嘗試用Guice重構一個項目。 我們的想法是將所有語言界面綁定到一個像法語波蘭語這樣的混合對象。

我們有一個綁定模塊:

public class StandardModule extends AbstractModule {

    @Override
    protected void configure() {

       bind(Language.class).to(Polish.class);

    }
 }

以及使用此注入對象的classe(AboutDialog.java):

@Inject Language language;

public AboutDialog(JFrame parent) {
    super(parent, "", true);
    this.language=language;
    this.setTitle(language.getLanguageInUse().getString("AboutDialog.title"));
    this.parent = parent;
    try {
        jbInit();
    } catch (Exception e) {
        e.printStackTrace();
    }
    pack();
}

我們有結果:

java.lang.NullPointerException at net.sf.jmoney.gui.AboutDialog.<init>(AboutDialog.java:67)

第67行是:

this.setTitle(language.getLanguageInUse().getString("AboutDialog.title"));

我們的界面是:

public interface Language {

    public ResourceBundle getLanguageInUse();
}

波蘭語課程是:

public class Polish implements Language {

    private ResourceBundle languageInUse;

    public Polish() {
        languageInUse = ResourceBundle.getBundle(Constants.LANGUAGE_PL);
    }

    public ResourceBundle getLanguageInUse() {
        return languageInUse;
    }


}

我們迷路了...

你正在使用“現場注射”。 這將使得在構造函數中使用注入的值變得困難; 即使Guice要創建對象(現在沒有發生)或者你要使用injector.injectMembers(aboutDialog) ,構造函數也會在注入器有機會注入你想要的字段之前運行。

創建一個采用變量參數和注入參數的類有點棘手。 這為您提供了一些選擇:

  • 注入JFrame。 如果您知道在創建構造函數時要使用的JFrame,那么只需使用bind(JFrame.class).toInstance(myJFrame); 在你的模塊中。 然后Guice可以完全創建AboutDialog。

  • 手動創建工廠。 這樣你可以注入AboutDialog.Factory並只需調用create來獲取你的AboutDialog 它看起來像這樣:

     public class AboutDialog extends JDialog { /** Injectable factory. */ public static class Factory { @Inject private Language language; public AboutDialog create(JFrame parent) { return new AboutDialog(parent, language); } } // no @Inject parameter; you're calling "new" yourself above! public AboutDialog(JFrame parent, Language language) { super(parent, "", true); this.language = language; // ... other initialization } } 
  • 創建一個工廠,讓Guice通過輔助注射為您打造

     public class AboutDialog extends JDialog { public interface Factory { public AboutDialog create(JFrame parent); } // you need the @Inject, and also the @Assisted to tell Guice to // use the parameter instead of Guice bindings @Inject public AboutDialog(@Assisted JFrame parent, Language language) { super(parent, "", true); this.language = language; // ... other initialization } } public class StandardModule extends AbstractModule { @Override protected void configure() { bind(Language.class).to(Polish.class); // here every method in AboutDialog.Factory will be implemented // to create the method's return type [AboutDialog] based on // the parameters (like JFrame) and the bindings (like Language) install(new FactoryModuleBuilder().build(AboutDialog.Factory.class)); } } 

如問題評論中所述,請確保您通過@Inject ed構造函數/字段或從Injector本身獲取AboutDialog (或AboutDialog.Factory ,否則Guice將不知道注入參數。

我假設你沒有在Guice的幫助下創建你的AboutDialog

你可以做的是使用injector.injectMembers(this) ,其中thisAboutDialog

最好的辦法是在AboutDialog將吉斯被創建的,所以所有成員都將被注入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM