上海app开发定制公司,东莞网站优化专家,wordpress不能发文章_只能在标题内写字,网站建设ppt方案模板下载jdk8 calendar勇敢的Java新世界的定义特征之一是Java空间中构建器模式的日益普及。 Groovy是JVM上最流行的替代语言#xff08;对于Java#xff09;#xff0c;以在核心库以及Groovy支持的库和框架中大量使用Builder而闻名。 Josh Bloch将该模式带到了Java开发人员社区的最前… jdk8 calendar 勇敢的Java新世界的定义特征之一是Java空间中构建器模式的日益普及。 Groovy是JVM上最流行的替代语言对于Java以在核心库以及Groovy支持的库和框架中大量使用Builder而闻名。 Josh Bloch将该模式带到了Java开发人员社区的最前沿并在其极具影响力的有效Java的第二版第2项中对此模式进行了介绍。 JDK中已经添加了几个构建器包括J2SE 1.7中添加了Locale.Builder 。 在本文中我将简要介绍JDK 8附带的 Calendar.Builder 。 如今Java开发人员通常通过以下任一方法填充Calendar类的实例 调用一个“ set”方法中的一个该方法接受实例的一长串内容或者通过依次调用该实例上的各个“ set”方法来实现。 接下来的两个代码清单演示了这两种填充Calendar实例的典型方法。 使用单个“设置”方法填充日历 /*** 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));
}使用多个单独的“设置”方法填充日历 /*** 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));
} 旁注在以上两个示例中我都使用了现代Java另一个日益流行的功能 static import 。 诸如ENGLISH YEAR和SECOND之类的常量实际上是从Locale和Calendar之类的类中静态导入的。 正如我之前所写 静态导入在Java开发人员中似乎越来越流行尤其是考虑到流畅接口的趋势。 上面显示的两种“传统”方法显示了填充Calendar实例的不同方法。 一种极端情况是分别设置每个单独的字段而另一种极端情况是使用单个“设置”方法设置所有有效字段。 每种方法都有其优势。 与多集方法相比单一“集”方法具有“未完成”对象的状态更少但是多集方法更具可读性因为基于每个“集”的第一个参数被设置值的名称是明确的“ 方法。 单集方法有点笨拙因为它需要六个整数可以很容易地将它们混合在一起以按顺序传递因为除了隐式阶数之外没有明显的方法可以区分哪个整数是哪个整数。 Calendar.Builder利用Bloch所描述的Builder的广告收益消除了“在[对象的]构造过程中出现不一致状态的情况”。 下一个代码清单中对此进行了演示。 Calendar.Builder允许具有可读设置的单语句实例化 /*** Demonstrate using JDK 8s 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));} 在上面的代码清单中创建了Calendar实例并将其填充在一条语句中从而消除了使对象在多个语句中处于不一致状态的风险。 此示例保留了传统的单个“集合”方法方法[ setintint ]的可读性并具有在实例化时立即完全填充对象的附加安全性。 对于希望提供较少的单个“设置”方法的开发人员 Calendar.Builder另一个机会是使用setDateintintint和setTimeOfDayintintint方法如下面的代码清单所示。 Calendar.Builder将日期和时间设置为两个呼叫 /*** Demonstrate using JDK 8s 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));
} 用这种方法键入的字符和行数较少但是它部分地重新引入了一个缺点即由于两个方法中的每一个都使用三个整数因此无意中切换了整数参数的可能性或者setTimeOfDay()的重载版本将占用一个整数setTimeOfDay()代表毫秒的第四个整数。 对于希望在实例化过程中指定Calendar参数时具有最大灵活性的开发人员 Calendar.Builder提供了setFieldsint…方法该方法采用任意长度的整数对其中整数对的第一个整数表示要设置的字段第二个整数表示要设置的字段表示该字段值的一对整数。 在下一个代码清单中使用此方法。 通过Calendar.Builder的setFields方法指定日历字段 /*** Demonstrate using JDK 8s 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 ...)方法带来更大的风险可能会破坏用于实例化Calendar新实例的整数的顺序但是使用静态导入的Calendar常数确实可以提高可读性并减少不正确混合整数的可能性。 如果提供了奇数个整数表示不完整对则抛出IllegalArgumentException 。 尽管Calendar.Builder在实例化和填充Calendar实例方面提供了一些便利但是只要幸运地采用JDK 8任何人都可以访问新的日期/时间API 因此可能会问“为什么使用Calendar.Builder”。 也许最好的答案是现在有成千上万的现有代码库线和框架有使用并期望Calendar的情况下所以它可能是一个漫长的时间之前需要Calendar完全消失如果有的话。 幸运的是 Calandar.Builder使得可以通过CalendarBulder.setInstantlong轻松将Instant 新Java数据/时间API的一部分实例转换成Calendar 。 下一个代码清单中对此进行了演示。 使用Calendar.Builder将Instant转换为Calendar /*** Demonstrate using JDK 8s 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)实例化都不应调用Calender.Builder上的其他“ set”方法来避免IllegalStateException 。 使用Calendar.toInstant可以很容易地朝另一个方向从Calendar获取Instant 。 JDK 1.8引入Calendar其他方法与提供当前实例的日历类型 作为字符串或可用日历类型集字符串集有关。 当我在系统上运行Calendar.getAvailableCalendarTypes时看到以下三个字符串“ gregory ”“ Japanese ”和“ buddhist ”与“ Supported Calendars”中记录的三个日历相同 结论 与许多Java开发人员一样 我期待标准Java开发套件中内置的改进的Java数据/时间API。 但是我也意识到尤其是在大型代码库中以及在使用期望使用Calendar或Date库和框架时我将在一段时间内无法摆脱Calendar和Date的困扰。 JDK 8中Calendar.Builder的引入减轻了这一负担。 参考来自JCG合作伙伴 Dustin Marx的JDK 8的Calendar.Builder来自Inspired by Actual Events博客。 翻译自: https://www.javacodegeeks.com/2013/05/jdk-8s-calendar-builder.htmljdk8 calendar