jdk8 calendar_JDK 8的Calendar.Builder
jdk8 calendar
勇敢的Java新世界的定義特征之一是Java空間中構(gòu)建器模式的日益普及。 Groovy是JVM上最流行的替代語言(對于Java),以在核心庫以及Groovy支持的庫和框架中大量使用Builder而聞名。 Josh Bloch將該模式帶到了Java開發(fā)人員社區(qū)的最前沿,并在其極具影響力的有效Java的第二版第2項中對此模式進行了介紹。 JDK中已經(jīng)添加了幾個構(gòu)建器,包括J2SE 1.7中添加了Locale.Builder 。 在本文中,我將簡要介紹JDK 8附帶的 Calendar.Builder 。
如今,Java開發(fā)人員通常通過以下任一方法填充Calendar類的實例:
調(diào)用一個“ set”方法中的一個,該方法接受實例的一長串內(nèi)容,或者通過依次調(diào)用該實例上的各個“ set”方法來實現(xiàn)。 接下來的兩個代碼清單演示了這兩種填充Calendar實例的典型方法。
使用單個“設(shè)置”方法填充日歷
/*** Demonstrate pre-JDK 8 method of instantiating Calendar instance using* "set" method for main fields.*/ public static void demoCalendarWithSingleSet() {final Calendar calendar =Calendar.getInstance(TimeZone.getTimeZone(timeZoneId),ENGLISH);calendar.set(2013, APRIL, 6, 15, 45, 22);out.println("Calendar via Constructor: " + stringifyCalendar(calendar)); }使用多個單獨的“設(shè)置”方法填充日歷
/*** Demonstrate pre-JDK 8 method of instantiating Calendar instance using* individual "set" calls for each pair of field names and values.*/ public static void demoCalendarWithIndividualSets() {final Calendar calendar =Calendar.getInstance(TimeZone.getTimeZone(timeZoneId),ENGLISH);calendar.set(YEAR, 2013);calendar.set(MONTH, APRIL);calendar.set(DATE, 6);calendar.set(HOUR, 3);calendar.set(MINUTE, 45);calendar.set(SECOND, 22);calendar.set(AM_PM, PM);out.println("Calendar via set methods: " + stringifyCalendar(calendar)); }旁注:在以上兩個示例中,我都使用了現(xiàn)代Java另一個日益流行的功能 : static import 。 諸如ENGLISH , YEAR和SECOND之類的常量實際上是從Locale和Calendar之類的類中靜態(tài)導(dǎo)入的。 正如我之前所寫 ,靜態(tài)導(dǎo)入在Java開發(fā)人員中似乎越來越流行,尤其是考慮到流暢接口的趨勢。
上面顯示的兩種“傳統(tǒng)”方法顯示了填充Calendar實例的不同方法。 一種極端情況是分別設(shè)置每個單獨的字段,而另一種極端情況是使用單個“設(shè)置”方法設(shè)置所有有效字段。 每種方法都有其優(yōu)勢。 與多集方法相比,單一“集”方法具有“未完成”對象的狀態(tài)更少,但是多集方法更具可讀性,因為基于每個“集”的第一個參數(shù),被設(shè)置值的名稱是明確的“ 方法。 單集方法有點笨拙,因為它需要六個整數(shù),可以很容易地將它們混合在一起以按順序傳遞,因為除了隱式階數(shù)之外,沒有明顯的方法可以區(qū)分哪個整數(shù)是哪個整數(shù)。
Calendar.Builder利用Bloch所描述的Builder的廣告收益:消除了“在[對象的]構(gòu)造過程中出現(xiàn)不一致狀態(tài)的情況”。 下一個代碼清單中對此進行了演示。
Calendar.Builder允許具有可讀設(shè)置的單語句實例化
/*** Demonstrate using JDK 8's Calendar.Builder to instantiate an instance of* Calendar using the set methods to set each field individually based on* field name and value.*/public static void demoCalendarWithCalendarBuilderSetFields(){final Calendar calendar =new Calendar.Builder().set(YEAR, 2013).set(MONTH, APRIL).set(DATE, 6).set(HOUR, 15).set(MINUTE, 45).set(SECOND, 22).setTimeZone(TimeZone.getTimeZone(timeZoneId)).setLocale(ENGLISH).build();out.println("Calendar via Calendar.Builder 'set' Fields: "+ stringifyCalendar(calendar));}在上面的代碼清單中,創(chuàng)建了Calendar實例并將其填充在一條語句中,從而消除了使對象在多個語句中處于不一致狀態(tài)的風(fēng)險。 此示例保留了傳統(tǒng)的單個“集合”方法方法[ set(int,int) ]的可讀性,并具有在實例化時立即完全填充對象的附加安全性。
對于希望提供較少的單個“設(shè)置”方法的開發(fā)人員, Calendar.Builder另一個機會是使用setDate(int,int,int)和setTimeOfDay(int,int,int)方法,如下面的代碼清單所示。
Calendar.Builder將日期和時間設(shè)置為兩個呼叫
/*** Demonstrate using JDK 8's Calendar.Builder to instantiate an instance of* Calendar using the "setDate" and "setTimeOfDay" builder methods.*/ public static void demoCalendarWithCalendarBuilderSetDaySetTime() {final Calendar calendar =new Calendar.Builder().setDate(2013, APRIL, 6).setTimeOfDay(15, 45, 22).setTimeZone(TimeZone.getTimeZone(timeZoneId)).setLocale(ENGLISH).build();out.println("Calendar via Calendar.Builder setDate/setTimeOfDay: "+ stringifyCalendar(calendar)); }用這種方法鍵入的字符和行數(shù)較少,但是它部分地重新引入了一個缺點,即由于兩個方法中的每一個都使用三個整數(shù),因此無意中切換了整數(shù)參數(shù)的可能性(或者setTimeOfDay()的重載版本將占用一個整數(shù)setTimeOfDay()代表毫秒的第四個整數(shù))。
對于希望在實例化過程中指定Calendar參數(shù)時具有最大靈活性的開發(fā)人員, Calendar.Builder提供了setFields(int…)方法,該方法采用任意長度的整數(shù)對,其中整數(shù)對的第一個整數(shù)表示要設(shè)置的字段,第二個整數(shù)表示要設(shè)置的字段表示該字段值的一對整數(shù)。 在下一個代碼清單中使用此方法。
通過Calendar.Builder的setFields方法指定日歷字段
/*** Demonstrate using JDK 8's Calendar.Builder to instantiate an instance of* Calendar using the setFields method that allows providing of Calendar* fields as key/value pairs.*/public static void demoCalendarWithCalendarBuilderSetPairs(){final Calendar calendar =new Calendar.Builder().setFields(YEAR, 2013, MONTH, APRIL, DATE, 6, HOUR, 15, MINUTE, 45, SECOND, 22).setTimeZone(TimeZone.getTimeZone("timeZoneId")).setLocale(ENGLISH).build();out.println("Calendar via Calendar.Builder setPairs: "+ stringifyCalendar(calendar));}此setFields(int ...)方法帶來更大的風(fēng)險,可能會破壞用于實例化Calendar新實例的整數(shù)的順序,但是使用靜態(tài)導(dǎo)入的Calendar常數(shù)確實可以提高可讀性,并減少不正確混合整數(shù)的可能性。 如果提供了奇數(shù)個整數(shù)(表示不完整對),則拋出IllegalArgumentException 。
盡管Calendar.Builder在實例化和填充Calendar實例方面提供了一些便利,但是只要幸運地采用JDK 8,任何人都可以訪問新的日期/時間API ,因此可能會問“為什么使用Calendar.Builder?”。 也許最好的答案是,現(xiàn)在有成千上萬的現(xiàn)有代碼,庫線,和框架有使用,并期望Calendar的情況下,所以它可能是一個漫長的時間之前需要Calendar完全消失(如果有的話)。 幸運的是, Calandar.Builder使得可以通過CalendarBulder.setInstant(long)輕松將Instant ( 新Java數(shù)據(jù)/時間API的一部分)實例轉(zhuǎn)換成Calendar 。 下一個代碼清單中對此進行了演示。
使用Calendar.Builder將Instant轉(zhuǎn)換為Calendar
/*** Demonstrate using JDK 8's Calendar.Builder to instantiate an instance of* Calendar based on "now" Instant.*/public static void demoCalendarWithCalendarBuilderInstant(){final Calendar calendar =new Calendar.Builder().setInstant(Instant.now().toEpochMilli()).setTimeZone(TimeZone.getTimeZone(timeZoneId)).setLocale(ENGLISH).build();out.println("Calendar via Calendar.Builder and Instant: " + stringifyCalendar(calendar));}請注意, setInstant方法的重載版本接受Date來實例化Calendar 。 在這兩種情況下,無論是使用setInstant(long)還是setInstant(Date)實例化,都不應(yīng)調(diào)用Calender.Builder上的其他“ set”方法來避免IllegalStateException 。
使用Calendar.toInstant()可以很容易地朝另一個方向(從Calendar獲取Instant ) 。 JDK 1.8引入Calendar其他方法與提供當(dāng)前實例的日歷類型 (作為字符串)或可用日歷類型集(字符串集)有關(guān)。 當(dāng)我在系統(tǒng)上運行Calendar.getAvailableCalendarTypes()時,看到以下三個字符串:“ gregory ”,“ Japanese ”和“ buddhist ”(與“ Supported Calendars”中記錄的三個日歷相同)
結(jié)論
與許多Java開發(fā)人員一樣 ,我期待標(biāo)準(zhǔn)Java開發(fā)套件中內(nèi)置的改進的Java數(shù)據(jù)/時間API。 但是,我也意識到,尤其是在大型代碼庫中,以及在使用期望使用Calendar或Date庫和框架時,我將在一段時間內(nèi)無法擺脫Calendar和Date的困擾。 JDK 8中Calendar.Builder的引入減輕了這一負擔(dān)。
翻譯自: https://www.javacodegeeks.com/2013/05/jdk-8s-calendar-builder.html
jdk8 calendar
總結(jié)
以上是生活随笔為你收集整理的jdk8 calendar_JDK 8的Calendar.Builder的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 低热量水果一览表 低热量水果有哪些
- 下一篇: gradle 安装_如何安装Gradle