2015-11-08 100 views
9

这是我从我的java教程开始研究的一个示例。 我有一个没有构造函数的Time1类,因此我期待它将默认值初始化为int,即零。类的实例变量的Java默认值未初始化为零

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

现在我有主类

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()方法返回00:00:00因为我没有使用任何方法来进行格式化之前应有System.out.println(thistime);,但是我得到的输出为12:00:00 AM,这相当于调用toString()方法。为什么在新对象初始化时默认调用此方法,即使没有被调用?

+3

为什么你期待'00:00:00'?你是否期望Java自动调用'toUniversalString'? – user2357112

+2

基本上,当你传递一个'Object'打印,像这样:'的System.out.println(对象)',它真的只是做'的System.out.println(Object.toString())' – Zizouz212

+1

@ user2357112,我不知道是什么方法被调用,为什么/如何,因此这个问题。谢谢你Zizouz212 – scott

回答

8

如果你使用像Eclipse的IDE,你可能已经注意到靠近你toString()方法,说overrides java.lang.Object.toString标记。这是在您尝试打印对象时默认调用的方法。这看起来像

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

由于您在方法内部具有相同名称的自定义,因此它将被覆盖。你可以注意到其中的差别,如果你重新命名自己的toString方法到别的东西,输出会是这样的[email protected]

+0

嗯,我没有注意到。点击它打开,其他类,并就为什么我自己的自定义类是给'AM/PM',而默认的是给一种存储位置感。 – scott

6

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

toString方法明确地返回12时hours == 0

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

              ------- 
+0

谢谢叶兰,但我并没有调用这个方法,那么,为什么在应用这个方法? – scott

+2

@scott当你试图打印一个对象时,它会调用'toString'。 – Eran

+0

谢谢。解答我的问题。 :) – scott

4

的System.out.println需要字符串参数,所以它要求你的ToString方法将你的时间1对象转换为一个字符串。由于你在那里有逻辑,你会看到“12:00:00 AM”输出。

你可以做

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

得到你所期望的输出;

4

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

当您打印对象(你有没有System.out.println(thistime)),其toString方法由默认调用(即使没有明确的调用)。就这么简单。

+0

这是错误的。 ''PrintStream.println()'被'Object'重载,其中显式调用'String.valueOf()'。 – xehpuk

8

问题出在您的toString方法中。什么下面确实

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

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

当你拨打:

System.out.println(thistime); 

打印结果会是一样的:

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

所以这就是为什么在调用toString方法。你可以写一些像((hour == 12) ? 12 : hour % 12)来修复它。

+0

它没有转换。 ''PrintStream.println()'被重载用于'Object',其中'String.valueOf()'被调用。 – xehpuk

0

print方法重载,对于任何不是原始的调用.toString()。印刷方法可以格式化的原始值,但对于任何Object子类调用toString()