Domanda

Prendete questa classe di base:

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

}

E questa classe derivata:

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

}

L'obiettivo è stato quello di chiamare solo mObj.doSomethingWith (mTheService); dopo la mTheService diventato valida (che è accaduto nella classe base). Cosa era sempre sputato NPE alla linea mObj. Posso capire perché quello che è successo, ma sembra wonky a me. Quindi questo è un bug o una caratteristica di DVM? Che ne dite di JVM?

È stato utile?

Soluzione

Questo è del tutto corretto, e si sarebbe verificato in "vanilla" Java troppo.

initializers variabile di istanza vengono eseguiti solo all'inizio del corpo del costruttore dopo il costruttore della superclasse è stata completata l'esecuzione. Così, mentre il costruttore XMPPSubservice è in esecuzione, mObj è nullo -. Quindi si chiama un metodo virtuale dal costruttore, e l'override in esegue PublicDataService

Morale: non chiamare metodi virtuali da costruttori, a meno che davvero è necessario, nel qual caso si dovrebbe documentare loro realmente cura. (Molto raramente è utile, ma si dovrebbe cercare è difficile evitarlo.) In pratica significa che si finisce con una chiamata su un oggetto potenzialmente parzialmente inizializzato, che è quello che sta succedendo qui.

Altri suggerimenti

Ho provato la seguente utilizzando implementazioni stub di oggetti in una VM Java.

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

Non NullPointerException.

mi sto perdendo qualcosa? Immagino che onServiceInstance deve effettivamente ottenere chiamato a seguito di context.getService(intent)?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top