Java仮想メソッド:機能またはバグ?
-
26-10-2019 - |
質問
この基本クラスを受講してください:
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.dosomeThing -with(mtheservice)のみを呼び出すことでした。 Mtheserviceが有効になった後(基本クラスで発生しました)。それは常にMOBJラインでNPEを吐き出したということでした。なぜそれが起こったのか理解できますが、それは私には不安定に見えます。それで、これはDVMのバグまたは機能ですか? JVMはどうですか?
解決
それは完全に正しいものであり、「バニラ」ジャバでも発生します。
インスタンス変数イニシャルアイザーは、コンストラクターボディの開始時にのみ実行されます 後 スーパークラスコンストラクターは実行を完了しました。だから XMPPSubservice
コンストラクターが実行しています、 mObj
nullです - その後、コンストラクターから仮想メソッドを呼び出し、オーバーライド PublicDataService
実行します。
道徳:あなたがいない限り、コンストラクターから仮想メソッドを呼び出さないでください 本当 その場合、それらを本当に注意深く文書化する必要があります。 (非常に時々それは便利ですが、それを避けるために一生懸命努力する必要があります。)基本的に、それはあなたがここで起こっている潜在的に重要なオブジェクトへの呼び出しになってしまうことを意味します。
他のヒント
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)
?