最近在優化項目代碼,看項目組的代碼時,發現了一個有趣的現象,有使用new Date().getTime()來獲取時間戳的, 也有使用System.currentTimeMillis()來獲取時間戳的,這讓我想到,好像我平時寫代碼也是想起哪種方式就用什麼方式寫。這兩種方式都可以,仔細思考一下,兩者應該會有區別的,應該有是最優的方式?
然後就看了看源碼,其實解決疑惑最優方式就是看源碼,打開java.util.Date的源碼可以發現,無參構造函數如下:
/**
* Allocates a <code>Date</code> object and initializes it so that
* it represents the time at which it was allocated, measured to the
* nearest millisecond.
*
* @see java.lang.System#currentTimeMillis()
*/
public Date() {
this(System.currentTimeMillis());
}
/**
* Allocates a <code>Date</code> object and initializes it to
* represent the specified number of milliseconds since the
* standard base time known as "the epoch", namely January 1,
* 1970, 00:00:00 GMT.
*
* @param date the milliseconds since January 1, 1970, 00:00:00 GMT.
* @see java.lang.System#currentTimeMillis()
*/
public Date(long date) {
fastTime = date;
}
從源碼可以看出,new Date().getTime()其實就是在無參構造裏調用了System.currentTimeMillis(),再傳入自己的有參構造函數。不難看出,如果只是僅僅獲取時間戳,即使是匿名的new Date()對象也會有些許的性能消耗, 從性能提升的角度來看,如果只是僅僅獲取時間戳,不考慮時區的影響(時區爲什麼會有影響),直接調用System.currentTimeMillis()會更好一些。
再來看看System.currentTimeMillis()的源碼:
/**
* Returns the current time in milliseconds. Note that
* while the unit of time of the return value is a millisecond,
* the granularity of the value depends on the underlying
* operating system and may be larger. For example, many
* operating systems measure time in units of tens of
* milliseconds.
*
* <p> See the description of the class <code>Date</code> for
* a discussion of slight discrepancies that may arise between
* "computer time" and coordinated universal time (UTC).
*
* @return the difference, measured in milliseconds, between
* the current time and midnight, January 1, 1970 UTC.
* @see java.util.Date
*/
public static native long currentTimeMillis();
這是一個本地方法,其時間來源依賴由操作系統爲其做了時區的處理,因此獲取時間戳,不需要考慮時區的前提下,它是最優選擇。
其實, java.util.Date設計來作爲格式化時間,以面向對象的方式獲取與時間有關的各方面信息,例如:獲取年月份、小時、分鐘等等比較豐富的信息。而new Date()來獲取當前時間更多的是因爲我們使用習慣導致經常第一時間想到用它來獲取當前時間。
擴展:關於獲取時間戳另一種方式:
在Java中,還可能見到另外一種獲取時間的方式:
Calendar.getInstance().getTimeInMillis()
其實這種方式是速度最慢的,看其源碼就會發現,Canlendar是區分時區的,因爲要處理時區問題會耗費很多的時間。