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 に答える