2012-03-19 21 views
6

Tengo una clase que amplía JPanel. En su constructor estoy pasando this a otros métodos, principalmente para agregar el objeto jpanel como un oyente a contenedores/controles dentro del jpanel (pero también a otros objetos). Dado que Netbeans muestra una advertencia leaking this in constructor para esas llamadas, las puse en otro método que se llama desde el constructor.Se está escapando esto en el constructor - dónde agregar oyentes y otros métodos que requieren "esto"

antes:

class Foo ... { 
    public Foo() { 
     initComponents(); 
     tabX.addChangeListener(this); // <- netbeans complains here 
    } 

después:

class Foo ... { 
    public Foo() { 
     initComponents(); 
     initListeners(); 
    } 

    protected void initListeners() { 
     tabX.addChangeListener(this); 
    } 

que se deshace de los síntomas. Pero dudo que solucione la razón por la cual Netbeans muestra la advertencia.
¿Dónde está el lugar adecuado para realizar este tipo de inicialización en una clase derivada de JPanel?

+0

no seguro de entender que se puede publicar la firma del método y su "fijar" – Woot4Moo

+0

esto podría ayudarle a http://stackoverflow.com/questions/3921616/java-leaking-this-in-constructor – Chikei

+0

[Java - Fugas esto en constructor] (http://stackoverflow.com/q/3921616/1048330) – tenorsax

Respuesta

0

Asumo que probablemente va a añadir su extensión JPanel a algún otro componente (por ejemplo JFrame, JApplet, otro JPanel, etc.). Usted mencionó que tiene una pequeña mezcla entre la necesidad de agregar el panel a los subcomponentes dentro de ese panel y "otros objetos" que el panel necesita escuchar. Probablemente sea mejor agregar el panel a esos "otros objetos" cerca del lugar donde agrega su extensión JPanel a su JFrame o a otro componente principal, fuera de la definición de clase de su extensión.

Sin embargo, para los subcomponentes de su panel que su panel debe escuchar, creo que lo que está haciendo está bien, siempre que esos subcomponentes no sean visibles para objetos fuera de su definición de clase de extensión JPanel. La advertencia está simplemente ahí para indicar que lo que estás haciendo puede ser inseguro, pero finalmente, cuando tu panel se recolecta basura, también lo harán todos los subcomponentes que posea, incluyendo cualquier lista de oyentes que mantengan que apunten a su extensión JPanel. Debido a este hecho, creo que poner la llamada add*Listener(this) en un método privado acertadamente llamado de su extensión JPanel y llamarlo desde su constructor está bien.

La otra opción sería usar Eclipse para que ya no reciba esas advertencias ... (totalmente en broma;).

0

El motivo de esta advertencia es que está pasando esto mientras el constructor no está terminado y, por lo tanto, el objeto no se ha inicializado por completo. Incluso si lo usa al final de su constructor, es probable que su clase esté extendida y haya un constructor de subclase que deba ejecutarse aún. En su caso (registrar el objeto como un oyente) esto es seguro, ya que Swing tiene un solo hilo y los eventos se transmitirán a los oyentes solo después de que se inicialice su objeto.

+1

Es una mala programación, incluso si se trata de un entorno de subproceso único. –

2

Me pregunto si hay un problema mayor en juego aquí: el de pedirle a su clase que haga demasiado. Una clase debe tener un objetivo principal, y una vista debe ser responsable de ver y eso es todo. Hacer que haga funciones de modelo o control y pierda cohesion, puede aumentar coupling y arriesgarse a crear objetos divinos difíciles o imposibles de depurar o extender. Entonces, para decirlo sin rodeos, su GUI o clases de vista deberían no también ser clases de oyentes. En otras palabras, no hay una buena razón y muchas malas razones para que una clase de GUI también implemente una interfaz de escucha.

La mejor solución: las clases de GUI no implementan oyentes.En su lugar, use clases internas anónimas, o clases internas privadas, o si es lo suficientemente complejo o anticipa extender y/o modificar su código en el futuro, clases de oyentes independientes.

+1

Para los oyentes independientes, el acceso [* package-private *] (http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) puede ser útil. – trashgod

+1

Sin embargo, las clases internas anónimas no resuelven el problema de la fuga 'esto', si sus instancias se crean en el constructor. Solo hace que el problema sea más difícil de detectar ya que ahora 'this' se filtra de manera implícita. –

Cuestiones relacionadas