tipos - Valor predeterminado de Java de variables de instancia de una clase no inicializada a cero para int
variable miembro de clase (6)
Esperaba System.out.println (esta vez); antes de utilizar el método setTime () para devolver 00:00:00 porque no he usado ningún método para reformatearlo, sin embargo obtengo el resultado como 12:00:00 AM, que es igual al método toString (). ¿Por qué se llamó a este método de manera predeterminada cuando se inicializa un nuevo objeto, incluso sin ser llamado?
Cuando imprime un objeto (lo cual hizo con System.out.println(thistime)
), se llama a su método toString
(incluso sin llamadas explícitas) de forma predeterminada. Es tan simple como eso.
Este es un ejemplo en el que estaba trabajando desde mi tutorial de Java. Tengo una clase Time1 que no tiene un constructor, y por lo tanto esperaba que se inicializara con los valores predeterminados en int, eso es cero.
public class Time1 {
private int hour; // expected to be initialised with zero
private int minute; // expected to be initialised with zero
private int second; // expected to be initialised with zero
public void setTime(int hour, int minute, int second) {
if (hour < 0 || hour >= 24 || minute < 0 || minute >= 60 || second < 0 || second >= 60) {
throw new IllegalArgumentException("value out of range");
}
this.hour = hour;
this.minute = minute;
this.second = second;
}
public String toUniversalString() {
return String.format("%02d:%02d:%02d", hour, minute, second);
}
public String toString() {
return String.format("%d:%02d:%02d %s", ((hour == 0 || hour == 12) ? 12 : hour % 12), minute, second, (hour < 12 ? "AM" : "PM"));
}
}
Y ahora tengo la clase principal
public class Time1test {
public static void main(String[] args) {
Time1 thistime = new Time1();
System.out.println(thistime);
thistime.setTime(13, 22, 33);
System.out.println(thistime);
}
}
Esperaba System.out.println(thistime);
antes de utilizar el método setTime()
para devolver 00:00:00 porque no he usado ningún método para reformatearlo, sin embargo setTime()
el resultado como 12:00:00 AM, que es igual al método toString()
. ¿Por qué se llamó a este método de manera predeterminada cuando se inicializa un nuevo objeto, incluso sin ser llamado?
Cuando llama a System.out.println(thistime);
para su objeto, se ejecuta su método toString
y se imprime la cadena que devuelve.
Su método toString
devuelve explícitamente 12 cuando hours == 0
:
return String.format("%d:%02d:%02d %s", ((hour==0 || hour==12)?12:hour%12),minute, second, (hour<12?"AM":"PM"));
-------
Si está utilizando un ide como eclipse, es posible que haya notado una marca cerca de su método toString () que dice que overrides java.lang.Object.toString
. Este es el método que se invoca por defecto cuando intenta imprimir un objeto. Esto se ve como
* @return a string representation of the object.
*/
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
Como tiene sus propias definiciones dentro del método con el mismo nombre, está siendo anulado. Puede notar la diferencia si cambia el nombre de su propio método toString
a otra cosa, y la salida sería algo así como Time1@2a139a55
System.out.println espera un parámetro String como, por lo que llama a su método toString para convertir su objeto Time1 en una cadena. Debido a la lógica que tienes ahí, estás viendo el resultado de "12:00:00 AM".
Tu puedes hacer
System.out.println(time1.toUniversalString());
para obtener el resultado que espera;
El problema está en tu método toString
. Lo que sigue a continuación
((hour==0 || hour==12)?12:hour%12)
es decir, siempre que el valor de la hora sea 0
o 12
, imprima 12; de lo contrario, imprima la hour % 12
.
Cuando usted llama:
System.out.println(thistime);
el resultado de impresión será el mismo que:
System.out.println(thistime.toString());
así que esta es la razón por la cual se invoca el método toString
. Puedes escribir algo como ((hour == 12) ? 12 : hour % 12)
para arreglarlo.
El método de print
está sobrecargado y llama a .toString()
para cualquier cosa que no sea primitiva. El método de impresión puede formatear valores primitivos pero llama a toString()
para cualquier subclase de Object
.