Xiaobaiは、チーズの製造期限を記録するプログラムを実装したいと考えていました。昨日のセルフテストの後、テストMMに提出され、テストが終了しました。テストMMがテストを終了した後、問題はないということでした。Xiaobaiは仕事を辞めました。MMをテストし、今朝自動回帰テストを行ったところ、バグを発見しました。
import java.util.Date;
public class Cheese {
public static final Cheese cheese=new Cheese();
private final long produceTimes;
private static final long produceDate =new Date(119,8,1).getTime();
private Cheese() {
produceTimes=new Date().getTime()-produceDate;
}
public long produceTimes() {
return produceTimes;
}
public static void main(String[] args) {
System.out.println("current time in day(from 1900:00:00) : "+new Date().getTime()/(1000*60*60*24L));
System.out.println("cheese had produces : "+ cheese.produceTimes()/(1000*60*60*24L) +" days");
}
}
Xiaobaiはテスト環境のコードをプルダウンしてデバッグし、実行結果が実際に間違っていることを発見しました。
current time in day(from 1900:00:00) : 18153
cheese had produces : 18153 days
昨日とテストMMは眩しかったですか?不可能!コードの問題である必要があります。履歴のコミットレコードを表示するために引き出されましたが、Xiaofanがプログラムに変更を加え、2行のコードの順序を変更したことがわかりました。交換前の手順は次のとおりです。
import java.util.Date;
public class Cheese {
private final long produceTimes;
private static final long produceDate =new Date(119,8,1).getTime();//这里
public static final Cheese cheese=new Cheese();//这里
private Cheese() {
produceTimes=new Date().getTime()-produceDate;
}
public long produceTimes() {
return produceTimes;
}
public static void main(String[] args) {
System.out.println("current time in day(from 1900:00:00) : "+new Date().getTime()/(1000*60*60*24L));
System.out.println("cheese had produces : "+ cheese.produceTimes()/(1000*60*60*24L) +" days");
}
}
演算結果:
current time in day(from 1900:00:00) : 18153
cheese had produces : 13 days
これはXiaobaiが望んでいる結果であり、テストMMが期待する結果でもあります。
底に着く
インスタンスの初期化も非常に特殊であることがわかりました。
-
staticフィールドは最初にデフォルト値に設定されます。ここで、cheeseはnullに設定され、produceDateは0に設定されます。
-
次に、静的イニシャライザが宣言の出現順に実行され
ます
。cheeseが最初に実行されると、Cheese()コンストラクタが呼び出され、produceDate = 0が値として使用されます。producedDateが最初に実行されると、producteDateは2019-09-01に設定されます、そしてcheese()コンストラクタを呼び出します。 - 最後に、コンストラクタからチーズクラスの初期化を返します。
さらに、私はまた新しいトリックを学びました
日付日付を2019-09-01に設定する理由
新しい日付(119,8,1)
ソースコードを見てください:
/**
* Allocates a <code>Date</code> object and initializes it so that
* it represents midnight, local time, at the beginning of the day
* specified by the <code>year</code>, <code>month</code>, and
* <code>date</code> arguments.
*
* @param year the year minus 1900.
* @param month the month between 0-11.
* @param date the day of the month between 1-31.
* @see java.util.Calendar
* @deprecated As of JDK version 1.1,
* replaced by <code>Calendar.set(year + 1900, month, date)</code>
* or <code>GregorianCalendar(year + 1900, month, date)</code>.
*/
@Deprecated
public Date(int year, int month, int date) {
this(year, month, date, 0, 0, 0);
}
その中で、年 は1900年からの年数、つまり2019-1900 = 119です。
月 は0から11までカウントされ、実際の月は1ずつ減らされる必要があります。つまり、9-1 = 8です。
日付 は1から31までカウントされ、実際の日は1になります。