Java class 的实例变量的默认值未针对 int 初始化为零

Java default value of instance variables of a class not initialized to zero for int

这是我在 java 教程中处理的示例。 我有一个没有构造函数的 Time1 class,因此我希望它用默认值初始化为 int,即零。

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"));
    }
}

现在我有了主要的 class

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);
    }
}

在使用 setTime() 方法到 return 00:00:00 之前,我期待 System.out.println(thistime); 因为我没有使用任何方法重新格式化它,但是我得到了输出为12:00:00 AM,相当于调用了toString()方法。为什么在初始化新对象时默认调用此方法,即使没有被调用?

当您为您的对象调用 System.out.println(thistime); 时,您的 toString 方法将被执行,并打印它 returns 的字符串。

你的 toString 方法显式 returns 12 当 hours == 0 :

return String.format("%d:%02d:%02d %s", ((hour==0 || hour==12)?12:hour%12),minute, second, (hour<12?"AM":"PM"));

                                          -------

System.out.println 需要一个字符串作为参数,因此它调用您的 toString 方法将您的 Time1 对象转换为一个字符串。由于其中的逻辑,您看到的是“12:00:00 AM”输出。

你可以做到

System.out.println(time1.toUniversalString());

获得您期望的输出;

I was expecting System.out.println(thistime); before using the setTime() method to return 00:00:00 because I haven't used any methods to reformat it, however I am getting the output as 12:00:00 AM, that is equal to calling toString() method. Why was this method being called by default when a new object is initialized, even without being called for?

当你打印对象(你用 System.out.println(thistime) 做的)时,默认调用它的 toString 方法(即使没有显式调用)。就是这么简单。

问题出在您的 toString 方法中。以下是什么

((hour==0 || hour==12)?12:hour%12)

是,每当 hour 的值是 012 时,打印 12,否则打印 hour % 12.

当你打电话时:

System.out.println(thistime);

打印结果与:

相同
System.out.println(thistime.toString());

所以这就是调用 toString 方法的原因。你可以写类似 ((hour == 12) ? 12 : hour % 12) 的东西来修复它。

如果您使用的是像 eclipse 这样的 ide,您可能会注意到方法 toString() 附近有一个标记,上面写着 overrides java.lang.Object.toString。这是您尝试打印对象时默认调用的方法。这看起来像

 * @return  a string representation of the object.
 */
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

因为您有自己的定义插入ide同名方法,它被覆盖了。如果您将自己的 toString 方法重命名为其他名称,您会注意到差异,并且输出类似于 Time1@2a139a55

print 方法被重载并调用 .toString() 用于任何非原始的。 print 方法可以格式化原始值,但会为任何 Object 子类调用 toString()