java虚拟方法: feature or bug?

标签 java dalvik jvm-languages

获取这个基类:

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 怎么样?

最佳答案

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

实例变量初始值设定项仅在父类(super class)构造函数完成执行后在构造函数体的开始处执行。因此,当 XMPPSubservice 构造函数正在执行时,mObj 为 null - 然后您从构造函数调用虚拟方法,并执行 PublicDataService 中的覆盖。

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

关于java虚拟方法: feature or bug?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8338145/

相关文章:

java - Jfreechart选择

java - 哪些对象导致 GC_EXPLICIT?

java - JVM 会被扩展以处理泛型吗?

java - 反编译 JVM 语言

java - 如何将shell脚本输出重定向到java控制台

java - 如何在android上为多个复选框动态添加 Action ?

java - Hibernate ORM 设计策略

java - DalvikVM 垃圾收集器会停止整个虚拟机吗?

android - AndFix 如何修补方法?

jvm - 为什么可以为 JVM 构建自定义语言,例如 Groovy、Scala、Clojure、Kotlin?