Programación General > Java

 Duda Con Swing

<< < (2/3) > >>

silverfox:

--- Citar ---a pesar de ser cierto que el operador == no se utiliza para comparar instancias, esto es efectivo siempre y cuando se desee comparar el contenido de los objetos.
--- Fin de la cita ---

Este código demuestra que te equivocas completamente:


--- Código: Text --- public class Test_Java2 {   int a;   Test_Java2(int i){    this.a= i;  }    public static void main (String args[]){    String aa= new String(&#34;test&#34;);    if(aa == &#34;test&#34;){      System.out.println(aa + &#34; == &#092;&#34;test&#092;&#34;&#34;);    }else{      System.out.println(aa + &#34; != &#092;&#34;test&#092;&#34;&#34;);    }     if(aa.equals(&#34;test&#34;)){      System.out.println(aa + &#34;.equals(&#092;&#34;test&#092;&#34;) == true&#34;);    }else{      System.out.println(aa + &#34;.equals(&#092;&#34;test&#092;&#34;) == false&#34;);    }    Test_Java2 t1= new Test_Java2(1);    Test_Java2 t2= new Test_Java2(1);        System.out.println(t1 == t2);        }    class Clase {    int a;        public Clase(int i){      this.a=i;    }  }} 
El operador == compara la posición en memoria de los objetos, mientras que equals() compara cada clase de la forma implementada por ella misma (ya que casi todas las clases sobreescriben éste método, generalmente, haciendo comparaciones campo por campo (si son primitivas), o llamando a los equals correspondientes (si son otros objetos).


Extraído de: http://www.devx.com/tips/Tip/12843

--- Citar ---The == operator returns true if the two handles on the left and right sides refer to the same location in memory. The function Object.equals() is intended to return true if two handles refer to logically equivalent instances.
--- Fin de la cita ---


Extraído de: http://java.sun.com/mailers/techtips/corej...006/tt0822.html


--- Citar ---Comparing with the == Operator

The == operator works on String object references. If two String variables point to the same object in memory, the comparison returns a true result. Otherwise, the comparison returns false, regardless whether the text has the same character values. The == operator does not compare actual char data. Without this clarification, you might be surprised that the following code snippet prints The strings are unequal.

String name1 = "Michèle";
String name2 = new String("Michèle");
if (name1 == name2) {
  System.out.println("The strings are equal.");
} else {
  System.out.println("The strings are unequal.");
}
      The Java platform creates an internal pool for string literals and constants. String literals and constants that have the exact same char values and length will exist exactly once in the pool. Comparisons of String literals and constants with the same char values will always be equal.

Comparing with the equals Method
The equals method compares the actual char content of two strings. This method returns true when two String objects hold char data with the same values. This code sample prints The strings are equal.

String name1 = "Michèle";
String name2 = new String("Michèle");
if (name1.equals(name2) {
  System.out.println("The strings are equal.");
} else {
  System.out.println("The strings are unequal.");
}
--- Fin de la cita ---


De todas formas, te funcionará bien, ya que en el fondo, estás comparando dos objetos idénticos, por ser ambos la misma referencia a memoria.


Un saludo.




Silverfox

escape:
silverFox, equals compara objetos. Por ejemplo, si usas un if == , dentro de un listener en swing, sirve. El equals devuelve un boolean, para comprobar si hablas de dos objetos iguales. Si quieres comparar los atributos del objeto, usas los 5 metodos de la API que sobreescriben al método. Sin embargo, un boton llamado "aceptar" es unico, asi lo declaras, no puedes tener dos botones en una misma clase llamados"aceptar". Ahora, si quieres comparar los atributos de un objeto que contenga campos tipo: nombre, edad, fecha, etc... logicamente el if no sirve, porque apunta a una dirección de memoria, la cual seria distinta a pesar que el objeto tenga los mismos campos.


Buena discusión. Es agradable este foro. Saludos.  :D

silverfox:
Hola...


--- Citar ---Sin embargo, un boton llamado "aceptar" es unico, asi lo declaras, no puedes tener dos botones en una misma clase llamados"aceptar".
--- Fin de la cita ---

¿Y qué? Lo que cuenta no es el nombre de la variable, sino la dirección de memoria a la que apunta. Naturalmente, no puedes hacer que una variable apunte a dos sitios distintos a la vez, pero sí que puedes tener dos variables apuntando al mismo sitio. Cuando tu Event hace referencia al objeto emisor, utiliza una referencia a memoria, no el nombre de la variable... Por eso funciona, en realidad, estás comparando dos direcciones de memoria, que da la casualidad de que son iguales y por eso te dí la razón.

A lo mejor es que no entendí tu primer razonamiento.


--- Citar ---El equals devuelve un boolean, para comprobar si hablas de dos objetos iguales.
--- Fin de la cita ---

¿Qué quieres decir con iguales? Es que, lamentablemente, si haces algo como:

--- Código: Text ---JButton a= new JButton();JButton b= a; 
a y b no es que sean iguales, sino que apuntan al mismo sitio -> son el mismo objeto.



--- Citar ---logicamente el if no sirve, porque apunta a una dirección de memoria, la cual seria distinta a pesar que el objeto tenga los mismos campos.
--- Fin de la cita ---

Lamentablemente, y en el caso del JButton en particular, entre muchos otros, un equals tampoco serviría para comprobar la igualdad entre los campos ;) Ejecuta esto, para comprobarlo:


--- Citar ---JButton a= new JButton("boton");
JButton b= new JButton("boton");
System.out.println((a==b )+"  "+a.equals(b ));

--- Fin de la cita ---


Por cierto, sí que puedes tener varias variables que se llamen igual, con distintos ámbitos. ;) (aunque no como variables de clase ambas, claro) ;)


Un saludo.



Silverfox

escape:
Hola.

Por parte. El nombre de la variable si que importa. A el efecto de declarar variables con el mismo nombre se le conoce como Shadowing. Por ejemplo:


--- Código: Text ---       public class Shadowing     {                            private int x;                 public static void main(String[] args)                {                                                   x = 6                                                       int x&#59;// variable repetida                           x = 5; // no existe error                           System.out.println(&#34;x = &#34; +x);                 }      }  
Si te fijas existen dos vatiables "x". Al mostrar por consola, se muestra x = 5, no x = 6. Esto se debe a un efecto de "ensombrecer" la variable de la clase. La variable que se utiliza es la definida dentro del ambiente más cercano. Apliquemos eso a lo que sucedia en mi aplicación:


--- Código: Text ---      public class Interfaz extends JFrame    {               private JButton resultado;            public Interfaz()          {               resultado = new JButton(&#34;Resultado&#34;);              resultado.addActionListener(new Eventos());           }                   private class Eventos implements ActionListener          {                   private LinkedList&#60;String&#62; resultado;                   public Eventos()                  {                         resultado = new LinkedList&#60;String&#62; ();                   }                   public void actionPerformed(ActionEvent e)                 {                        if(e.getSource() == resultado)                       {                               // hacer algo                       }                  }        }}        


En el código anterior, declaré por error dos variables con el mismo nombre:"resultado". Una es un botón y la otra una colección. El problema es que la colección es quien actúa en el metodo actionPerformed, no el botón. ¿Por qué?, simplemente por Shadowing de la variable. Si cambias el nombre del LinkedList a otro distinto, el programa funciona perfectamente.

Lo de equals lo comprendo, sé que compara referencias en la memoria. El método e.getSource() entrega la fuente del evento y se compara con el componente que gatilló la acción. Estrictamente hablando, e.getSource() no reconoce que componente se ha presionado en la interfaz, no sabe si es un botón, un combobox, etc. Si deseas acotar entonces además del equals, debes usar un cast:


--- Código: Text ---   public void actionPerformed(ActionEvent e) {         JButton boton = (JButton)e.getSource();      if(boton.equals(boton1))     {        // hacer algo     }      if(boton.equals(boton2))   {     // hacer algo    }}  

Ahora, parece que no me explique bien con respecto a comparar contenido y no referencias. Mira este ejemplo:


--- Código: Text ---    public class A  {      private String nombre;     private String apellido;      public A()     {          nombre = new String();         apellido = new String();     }     public A(String nombre, String apellido)    {         this();        this.nombre = nombre;        this.apellido = apellido;    } }       public class B    {           public static void main(String[] args)          {                 A a1 = new A(&#34;Miguel&#34;, &#34;Andrade&#34;);                 A a2 = new A(&#34;Miguel&#34;, &#34;Andrade&#34;);                  // ambos objetos tienen los mismos campos                 // pero apuntan a sectores distintos de memoria                 if(a1.equals(a2))                {                     System.out.println(&#34;iguales&#34;);                 }                 else                 {                     System.out.println(&#34;distintos&#34;);                 }            }       }   
El código de arriba siempre mostrara "distintos" a pesar de que los objetos poseen el mismo nombre y apellido. En ese caso, sobreescribir equals presenta la utilidad, ya que compara el contenido de los objetos.

silverfox:
Hola...

Vamos a ver...


--- Citar ---
--- Código: Text ---    public class Shadowing    {                          private int x;                public static void main(String[] args)               {                                                 x = 6                                                     int x;// variable repetida                          x = 5; // no existe error                          System.out.println(&#34;x = &#34; +x);                }     } 
--- Fin de la cita ---

Tu código no está enmascarando nada, supongo que lo habrás escrito de memoria. De hecho, tiene un error por el que no puede ni siquiera ser compilado. (Supongo que lo habrás escrito de memoria, pero la variable Shadowing.x no existe en el main y, de existir, ni siquiera se tendría acceso a ella, porque la definiste como privada. Cuestión de visibilidad).

Pero bueno, se ve bastante bien el ejemplo de enmascaramiento que querías mostrar.

Ciertamente, en tu aplicación existe ese efecto colateral (porque no es un error, en realidad, todo está bien). Por cierto... ¿para qué comparas en el evento con la fuente del mismo? ¿No es más fácil añadir un ActionListener a cada botón por separado, o es que se requiere lo que estás haciendo aquí?



--- Citar ---
--- Código: Text --- public class A {     private String nombre;    private String apellido;     public A()    {         nombre = new String();        apellido = new String();    }    public A(String nombre, String apellido)   {        this();       this.nombre = nombre;       this.apellido = apellido;   } } 
--- Fin de la cita ---

Aquí estás generando 2 veces las variables de String... new String() genera una cadena vacía, y luego la estás sustituyendo por una constante, en el constructor con parámetros.
Naturalmente, son 2 objetos que tienen localizaciones de memoria diferentes, pero no veo en qué se diferencia este código de uno mío un poco más arriba en esta misma discusión.



--- Citar ---Lo de equals lo comprendo, sé que compara referencias en la memoria.
--- Fin de la cita ---
No entendiste del todo:

Como todos habreis podido observar, el == siempre compara referencias en memoria de las variables, lo que significa que a==b significa, no que a y b sean dos objetos iguales, sino que son el mismo (como ya dije antes).

Por contra, el método equals() funciona de forma un poco diferente:
Object.equals(), JButton.equals() y otros, sí comparan referencias a memoria, porque es el comportamiento por defecto de equals(). Sin embargo, otras (como String, Integer y otras), comparan contenidos.
Por si a alguien le interesa saber cuáles sí y cuales no, echad un vistazo al interfaz Comparable. Lo habitual es que, si una clase implementa este interfaz, también tenga sobreescrito el método equals, según las especificaciones del API de Java (1.4.2 y 1.5.0, según he comprobado)



Un saludo.




Silverfox

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

[*] Página Anterior

Ir a la versión completa