2

采取这个基类:

public abstract class XMPPSubservice
{

    protected XMPPService mTheService;


    protected XMPPSubservice(Context context) 
    {
        Intent intent = new Intent(context, XMPPService.class);
        context.startService(intent);
    }


    public void onServiceInstance(XMPPService service) {
        // TODO Auto-generated method stub
        mTheService = service;
    }

}

而这个派生类:

public class PublicDataSubservice extends XMPPSubservice 
{

    private final SomeObject mObj = new SomeObject();

    public PublicDataSubservice(Context context) {
        super(context);
    }

    @Override
    public void onServiceInstance(XMPPService service) 
    {
        super.onServiceInstance(service);
            mObj.doSomethingWith(mTheService);
    }

}

目标是只调用 mObj.doSomethingWith(mTheService); 在 mTheService 生效之后(发生在基类中)。问题是它总是在 mObj 线上吐出 NPE。我可以理解为什么会这样,但对我来说这看起来很奇怪。那么这是 DVM 的错误还是功能?JVM怎么样?

4

2 回答 2

5

这是完全正确的,并且也会出现在“香草”Java 中。

实例变量初始化器仅在超类构造函数完成执行在构造函数主体的开头执行。因此,当XMPPSubservice构造函数正在执行时,mObj为 null - 然后您从构造函数调用一个虚拟方法,并执行覆盖PublicDataService

道德:不要从构造函数调用虚方法,除非你真的必须这样做,在这种情况下你应该非常仔细地记录它们。(偶尔它很有用,但你应该尽量避免它。)基本上这意味着你最终会调用一个可能部分初始化的对象,这就是这里发生的事情。

于 2011-12-01T08:06:39.680 回答
1

我在 Java VM 中使用对象的存根实现尝试了以下操作。

public static void main(String[] args) {
    Context context = new Context();
    PublicDataSubservice pds = new PublicDataSubservice(context);
    XMPPService service = new XMPPService();
    pds.onServiceInstance(service);
}

没有NullPointerException

我错过了什么吗?我想这onServiceInstance实际上必须因为context.getService(intent)?

于 2011-12-01T09:14:06.183 回答