Je voudrais un peu d'aide pour comprendre comment définir un objet sur null fonctionne dans Java. J'ai une situation où, apparemment, à première vue, il semble qu'un objet qui est défini sur null, n'est soudainement pas nul, mais évidemment, cela ne peut pas être le cas.Définition de l'objet à null et du flux de programme dans Java
J'ai une classe dans laquelle je crée un objet. Cet objet est une scène. Il s'agit d'un projet Open GL ES 2.0, donc les méthodes render() et updateLogic() de cette scène sont appelées depuis onDrawFrame (ceci est contrôlé via un gestionnaire de scène afin que nous puissions facilement changer de scène).
Alors, je pourrais avoir quelque chose comme ça (code abattrez pour le but de la question):
public class MyGLRenderer implements GLSurfaceView.Renderer{
MyScene myScene;
SomeOtherScene someOtherScene;
public void createScenes(){
myScene = new MyScene(this);
someOtherScene = new SomeOtherScene(this);
SceneManager.getInstance().setCurrentScene(myScene);
}
public void cleanUp(){
myScene = null;
Log.v("tag","myScene (from MyGLRenderer) is: "+myScene);
SceneManager.getInstance().setCurrentScene(someOtherScene); //Scene changed but this won't take effect until the next 'tick'
}
@Override
public void onDrawFrame(GL10 gl) {
SceneManager.getInstance().getCurrentScene().updateLogic();
SceneManager.getInstance().getCurrentScene().render();
}
}
Dans la situation ci-dessus, le traitement est tourné vers myScene qui ressemblerait à quelque chose comme ça :
public class MyScene implements Scene{
MyGLRenderer renderer;
public myScene(MyGLRenderer renderer){
this.renderer = renderer;
}
@Override
public void render(){
//Render something here
}
@Override
public void updateLogic(){
doSomething();
//The condition here could be anything - maybe the user taps the sceen and a flag is set in onTouchEvent for example
if (someConditionIsMet){
renderer.cleanup();
}
Log.v("tag","myScene (from within myScene) is: "+this);
}
}
Alors, quand je mis la scène en utilisant mon manager de scène, le traitement est tourné vers cette scène et il est updateLogic et les méthodes se rendre appelé à partir onDrawFrame en continu. Quand j'ai couru mon code, j'ai été surpris qu'il ne plante pas avec une exception NullpointerException. Les journaux étaient comme ceci:
myScene (from within myScene) is: [email protected]
myScene (from within myScene) is: [email protected]
myScene (from within myScene) is: [email protected]
myScene (from within myScene) is: [email protected]
myScene (from within myScene) is: [email protected]
myScene (from within myScene) is: [email protected]
myScene (from within myScene) is: [email protected]
myScene (from within myScene) is: [email protected]
myScene (from MyGLRenderer) is: null
myScene (from within myScene) is: [email protected]
Comme vous pouvez le voir, « myScene » est valable jusqu'à la méthode cleanUp() est appelée et fixe à null. Mais le code retourne ensuite à myScene pour finir, où il est toujours valide (pas nul). Je voudrais vraiment comprendre comment fonctionne la chose en Java - pourquoi semble-t-il être nul une minute (ou d'un endroit) et puis pas (d'un endroit différent)?
Merci @StefanHaustein, OK qui fait genre de sens. Je suis probablement en train de mal comprendre les choses. Donc, parce que l'objet est toujours utilisé (ses méthodes render() et updateLogic() sont toujours appelées), il ne peut pas être GC'd et reste donc actif jusqu'à ce que le système d'exploitation le considère comme libre. '- même si la référence réelle qui lui a été assignée lors de son installation est maintenant nulle (et il n'existe aucune autre' référence 'réelle, c'est-à-dire, comme this.myScene = myScene dans une autre classe quelque part)? – Zippy
Je pense que le gestionnaire de scène s'y tient toujours, a clarifié ma réponse en conséquence. –
Theres reste une référence à l'objet car la pile d'appels doit retourner d'une méthode d'instance sur l'objet. Aussi, comme l'a dit stefan, l'objet est annulé, la référence dans le moteur de rendu est. –