tutorial tooltiptext interfaz grafica español ejemplos componentes java object field this

tooltiptext - java swing tutorial pdf español



¿Está alguna vez justificado tener un objeto que se tenga a sí mismo como campo? (9)

¿Alguna vez se justifica tener un objeto que se tiene a sí mismo como un campo como este?

class Thing { Thing field; public Thing() { this.field = this; } }

No estoy hablando de una clase con un campo del mismo tipo pero una clase hecha para que cada instancia de la clase se tenga a sí misma como un campo. Acabo de ver esto en algún código heredado (este campo nunca se usó), así que tengo curiosidad. ¿Algún uso legítimo de esto?


Caso de reflexión con controles de interfaz de usuario de la biblioteca.

Es completamente legítimo en ciertos patrones de uso. En el marco empresarial no divulgado, he visto XML como este ejemplo simplificado:

<form> <comboBox listItems="order.LineItems" displayMember="description" valueMember="selfRef"/> </form>

Los enlaces del control a los valores se realizan a través de Reflection . Si está contento con solo la Integer ID como valueMember , no necesita la referencia de los miembros de la clase al objeto en sí. Pero si desea referencia al objeto en sí Y por diseño, el valor vacío ( "" ) no se implementa como un caso especial que significa this , entonces necesita mantener esto en una variable miembro ( selfRef en el ejemplo anterior).


El único caso en el que puedo pensar es para algunos tipos de refactorización. Para crear un ejemplo, un objeto puede haber comenzado como una colección de métodos estáticos que no están muy orientados a objetos:

public static void doItToIt(Foo it) { if (it.getType().equals("bar")) { it.setSomeVariable(value); it.manipulate(); } else { // do nothing } }

... así que decidimos deshacernos de getType() y convertirlo en una relación de subclase, y al refactorizar, la cosa fue copiada y pegada para hacer el código más limpio y más orientado a objetos, lo que requería:

public class Bar extends Foo { private Bar it = this; private String getType() { return "bar"; } public void doItToIt() { if (it.getType().equals("bar")) { it.setSomeVariable(value); it.manipulate(); } else { // do nothing } } }

Si hubiera un solo método como este, sería mejor usar una variable local:

public void doItToIt() { final Bar it = this; ... }

pero si hay varios, usar una variable de instancia haría que el código funcione más rápido.

Ahora sería mejor ir y reemplazar todas las instancias de it con this (y deshacerse de getType() , y eliminar el if , y así sucesivamente) pero como un paso intermedio sigue siendo una mejora, y podría quedar en ese indique si hay (o se cree que existen) otras cosas más importantes que hacer.

Otra posibilidad sería copiar el pseudocódigo de algo así como una especificación en la que this tiene un nombre en el pseudocódigo y está intentando deliberadamente hacer coincidir la estructura del pseudocódigo para facilitar la comparación de la implementación con la especificación. (Y, nuevamente, si tuviera múltiples métodos, entonces usar una variable local provocaría la repetición).

Pero en términos generales, no, tener una variable de instancia que siempre se refiere a this es redundante y, por lo tanto, impide la claridad.


En iOS, los objetos suelen tener delegados, normalmente otro objeto que puede proporcionar datos, o pueden hacer otras cosas necesarias para que un objeto funcione correctamente, como alternativa a la creación de subclases. Si un objeto implementa toda la funcionalidad en sí misma que el delegado debería implementar, entonces el objeto puede ser su propio delegado. No es totalmente común, pero tampoco es raro.

Digamos que tienes un "jefe" que tiene una "secretaria", una "cafetera" y un "conductor". El jefe obviamente puede escribir sus propias cartas, hacer su propio café y conducir él mismo, pero no todos los jefes lo hacen. Por lo tanto, a veces uno o más de estos campos se establecerán en "esto".


No porque sería redundante tenerse a sí mismo como campo cuando tiene la palabra clave this

Dentro de un método de instancia o un constructor, this es una referencia al objeto actual: el objeto cuyo método o constructor se está llamando. Puedes referirte a cualquier miembro del objeto actual desde un método de instancia o un constructor usando this . "- Palabra clave Javadocs" this "


No, en mi opinión, esto nunca está justificado, porque cada objeto implícitamente ya tiene ese campo: this . Por supuesto, está justificado que un objeto tenga un campo que a veces, pero no siempre, se refiera a sí mismo (lo que podría ocurrir, por ejemplo, en una lista cíclica vinculada), pero la pregunta es sobre un campo que siempre se refiere al objeto sí mismo.

He visto un código donde dicho campo se usa para poder referirme al objeto que contiene desde (anónimo) desde clases internas, pero también en ese caso esto no es necesario. Puedes usar ContainingClass.this . Por ejemplo:

class A { class B { A getParent() { return A.this; } } }


Otro ejemplo en JDK - java.lang.Throwable

private Throwable cause = this;

El campo de cause puede estar en 3 estados: sin configurar; establecido en nulo; establecer en otro Throwable.

El implementador usa this para representar el estado no establecido.

Una estrategia más legible es probablemente definir un valor centinela para unset

static Throwable UNSET = new Throwable(); private Throwable cause = UNSET;

por supuesto, hay una dependencia recursiva - UNSET.cause=? - que es otro tema divertido.


Podría justificarse si el objeto al que se hace referencia se puede cambiar después, pero el valor inicial es el this (aunque dicho diseño también debe revisarse, porque puede indicar que Thing tiene más responsabilidades de las que debería).

Sin embargo, si el objeto al que se hace referencia es siempre this , entonces es innecesario y confuso.

La siguiente declaración no solo es confusa, sino también divertida :)

private final Thing thing = this;


Puedo pensar al menos en un ejemplo donde está justificado. p.ej

Tengo una cadena de certificados donde cada enlace de la cadena tiene una referencia a su padre. En la parte superior de la cadena, el último certificado está auto firmado, por lo que su padre es el suyo.

En resumen, realmente depende del espacio problemático que está modelando. Cualquier afirmación absoluta que afirme que esto no debe hacerse sufre de falta de imaginación.

public class Cert { public Cert parent; } public class SelfSignedCert extends Cert { public SelfSignedCert() { this.parent = this; } }


Sí, aunque esto es raro Esto se usa en el JDK para situaciones en las que el campo podría ser this pero podría no serlo.

De la clase que implementa Collections.synchronizedCollection(c)

static class SynchronizedCollection<E> implements Collection<E>, Serializable { private static final long serialVersionUID = 3053995032091335093L; final Collection<E> c; // Backing Collection final Object mutex; // Object on which to synchronize SynchronizedCollection(Collection<E> c) { this.c = Objects.requireNonNull(c); mutex = this; } SynchronizedCollection(Collection<E> c, Object mutex) { this.c = Objects.requireNonNull(c); this.mutex = Objects.requireNonNull(mutex); }

En este caso, el mutex podría ser la clase actual, sin embargo, si esta colección se obtiene de una colección sincronizada existente, el mutex podría ser diferente. por ejemplo, si llama a Map.values() y el Map es un synchronizedMap el mutex será el mapa, no la colección.

Otro ejemplo es Throwable que apunta a sí mismo como la causa por defecto.

/** * The throwable that caused this throwable to get thrown, or null if this * throwable was not caused by another throwable, or if the causative * throwable is unknown. If this field is equal to this throwable itself, * it indicates that the cause of this throwable has not yet been * initialized. * * @serial * @since 1.4 */ private Throwable cause = this;