2012-11-08 118 views
12

我们试图用Guice重构一个项目。这个想法是将界面的所有界面绑定到像法国波兰这样的混凝土物体。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; 
    } 


} 

我们输了...

+0

你应该改变你的代码一点点,看看那里的NPE被抛出 '代码 资源包捆= language.getLanguageInUse(); 字符串标签= bundle.getString(“AboutDialog.title”); ' –

+0

空对象是语言。我们认为注射不起作用。 – user1810567

+0

你如何创建AboutDialog?我不认为你正在与Guice创建对话框,因为Guice需要一个空构造函数,或者你需要将jframe绑定到某个地方? –

回答

8

我假设你不与帮助创建AboutDialog的Guice。

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

最好的方法是将由Guice创建AboutDialog,因此所有成员都将被注入。

7

您正在使用“现场注入”。这将使它很难在构造函数中使用注入的值;即使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 
        } 
    } 
    
  • 通过assisted injection为你创建一个工厂,让吉斯线起来。

    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)); 
        } 
    } 
    

如问题的意见指出,要确保你得到你的AboutDialog(或通过@Inject ED构造函数/场或从Injector本身,否则AboutDialog.Factory吉斯不知道要注入参数

+0

10我们已成功注入对象和项目完美运作。感谢您的帮助^^。 – user1810567

+0

不客气!如果问题解决了,请记住[接受答案](http://stackoverflow.com/faq#howtoask)。祝你的项目好运! –

+1

这句话“构造函数将在注入器有机会注入你想要的字段之前运行”这一句节省了我的一天,因为我不理解为什么我的默认构造器中使用的注入字段是空的。谢谢!!! – mljrg