java - metodo - Cómo imprimir la dirección de un objeto si ha redefinido el método toString
tostring java español (5)
Soy un novato en Java. Ahora estoy estudiando iguales y == y redefinición de iguales y toString.
Me gustaría usar tanto el método toString que he redefinido como el método predeterminado que se hereda de la clase Object.
No pude usar ese super modificador para alcanzar ese método.
Esto es sólo con fines educativos. Lo que me gustaría obtener es más claro si echa un vistazo a los comentarios en mi código.
¿Podrías ayudarme aquí?
Mi código es:
public class EqualTest{
public static void main(String[] args){
Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15);
//System.out.super.println(alice1);
Employee alice2 = alice1;
//System.out.super.println(alice2);
Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15);
//System.out.super.println(alice3);
System.out.println("alice1==alice2: " + (alice1==alice2));
System.out.println("alice1 == alice3: " + (alice1==alice3));
System.out.println("alice1.equals(alice3): " + alice1.equals(alice3));
}
}
class Employee{
...
public String toString(){
return getClass().getName() + "[name = " + name +
", salary=" + salary + ", hireDay=" + hireDay + "]";
}
}
Aquí hay una respuesta en profundidad sobre la anulación de iguales y hashcode
¿Qué problemas se deben considerar cuando se reemplaza equals y hashCode en Java?
El punto clave es La relación entre los dos métodos es:
Siempre que a.equals (b), entonces a.hashCode () debe ser igual que b.hashCode ().
Estrictamente hablando, no puede imprimir la dirección de un objeto en Java puro. El número que parece una dirección de objeto en la Cadena producida por Object.toString()
es el "código hash de identidad" del objeto. Puede o no estar relacionado con la dirección actual del objeto:
Las especificaciones no indican cómo se calcula el número de hash de identidad. Se deja deliberadamente sin especificar.
Dado que el número es un código hash, no puede cambiar. Entonces, aunque (típicamente) está relacionado con una dirección de objeto, esa será la dirección del objeto en el momento en que se accedió al código hash por primera vez . Esto podría ser diferente a su dirección actual, y será diferente si el GC ha movido el objeto desde la primera vez que se observó el código hash de identidad del objeto.
En una JVM de 64 bits (con un tamaño de pila suficientemente grande / que no utiliza oops comprimidos) las direcciones no cabrán en un número de código de hash de identidad que se devuelve como un
int
.
De todos modos, la forma de obtener este número es llamar a System.identityHashCode(obj)
.
Si realmente desea la dirección actual de un objeto, puede obtenerla utilizando JNI y un método nativo (y alguna ruptura de abstracción), o usando métodos en la clase Unsafe
. Pero tenga en cuenta que estos dos enfoques no son portátiles ... y que las direcciones de los objetos que le dan son susceptibles de "romperse" cuando se ejecuta el GC.
Para los que dudan, esto es lo que dicen los javadocs de Java 10 en el punto "hashcode! = Address":
"(El hashCode puede o no implementarse como una función de la dirección de memoria de un objeto en algún momento ).
Énfasis añadido. De hecho, con las JVM recientes, el comportamiento predeterminado es NO basar el código hash en una dirección de memoria. Así ha sido desde al menos Java 7.
Para confirmar esto, incluya -XX:+PrintFlagsFinal
para averiguar qué es lo que determina por defecto el indicador de hashcode
, y luego observe el código fuente de OpenJDK para ver qué significa. (El código está en el archivo "vm / runtime / synchronizer.cpp" en algunas versiones, pero en YMMV).
Puede crear otro método dentro de su clase Employee para usar el método super toString.
Ver ejemplo:
public class Employee {
public String toString() {
return "MyToStringMethod";
}
public String superToString() {
return super.toString();
}
public static void main(String[] args) {
Employee b = new Employee();
System.out.println(b);
System.out.println(b.superToString());
}
}
o combinar ambos en un método:
public class Employee {
public String toString() {
return super.toString() + " MyToStringMethod";
}
public static void main(String[] args) {
Employee b = new Employee();
System.out.println(b);
}
}
Puede llamar al método super () para ejecutar el método de superclase correspondiente.
class Employee{
...
public String toString(){
String s = super.toString();
return getClass().getName() + "[name = " + name +
", salary=" + salary + ", hireDay=" + hireDay + "]" + s;
}
toString () en la clase Object es la siguiente
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
Si desea lograr una especie de comportamiento predeterminado a toString()
, puede utilizar el método System.identityHashCode()
. El toString()
predeterminado se verá así:
public String toString(Object o) {
return o.getClass().getName() + "@" +
Integer.toHexString(System.identityHashCode(o));
}