Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。 Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等。

新特性

Java8 新增了非常多的特性,我们主要讨论以下几个:

  • Lambda 表达式 − Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
  • 方法引用 − 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
  • 默认方法 − 默认方法就是一个在接口里面有了一个实现的方法。
  • 新工具 − 新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。
  • Stream API −新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
  • Date Time API − 加强对日期与时间的处理。
  • Optional 类 − Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
  • Nashorn, JavaScript 引擎 − Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。

    Java Lambda 表达式

    Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
    Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
    使用 Lambda 表达式可以使代码变的更加简洁紧凑。

    语法

    lambda 表达式的语法格式如下:
    1. (parameters) -> expression
    2. (parameters) ->{ statements; }
    注意:lambda表达式主要是用于匿名内部类。

    Lambda 表达式实例

    Lambda 表达式的简单例子: ```java // 1. 不需要参数,返回值为 5
    () -> 5

// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x

// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y

// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y

// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)

  1. ```java
  2. public static void main(String[] args) {
  3. InterA interA = new InterA() {
  4. @Override
  5. public void a() {
  6. System.out.println("a");
  7. }
  8. };
  9. interA.a();
  10. InterA interA1 = ()-> System.out.println("a");
  11. interA1.a();
  12. }
  13. interface InterA{
  14. void a();
  15. }
  1. public static void main(String[] args) {
  2. InterA interA = ()-> 10;
  3. }
  4. interface InterA{
  5. int a();
  6. }
  1. public static void main(String[] args) {
  2. InterA interA = (m)-> 10;
  3. }
  4. interface InterA{
  5. int a(int x);
  6. }
  1. public static void main(String[] args) {
  2. InterA interA = (m,n)-> 10;
  3. }
  4. interface InterA{
  5. int a(int x,int y);
  6. }

Java 8 方法引用

方法引用使用一对冒号 :: 。
当在匿名内部类中调用一个方法的时候,可以简写!但是参数需要对应起来

  1. public static void main(String[] args) {
  2. InterA interA = (s)->{
  3. return new Test().m1(10);
  4. };
  5. InterA interA1 = new Test()::m1;
  6. InterA interA2 = Test::m2;
  7. }
  8. interface InterA{
  9. int a(int a);
  10. }
  11. public int m1(int x){
  12. System.out.println("m1...");
  13. return 10;
  14. }
  15. public static int m2(int y){
  16. System.out.println("m2...");
  17. return 10;
  18. }

方法引用实例

在 Java8Tester.java 文件输入以下代码:

  1. import java.util.List;
  2. import java.util.ArrayList;
  3. public class Java8Tester {
  4. public static void main(String args[]){
  5. List<String> names = new ArrayList();
  6. names.add("Google");
  7. names.add("Runoob");
  8. names.add("Taobao");
  9. names.add("Baidu");
  10. names.add("Sina");
  11. names.forEach(System.out::println);
  12. }
  13. }

Java 8 默认方法

Java 8 新增了接口的默认方法。
简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法。
我们只需在方法名前面加个 default 关键字即可实现默认方法。

为什么要有这个特性? 首先,之前的接口是个双刃剑,好处是面向抽象而不是面向具体编程,缺陷是,当需要修改接口时候,需要修改全部实现该接口的类,目前的 java 8 之前的集合框架没有 foreach 方法,通常能想到的解决办法是在JDK里给相关的接口添加新的方法及实现。然而,对于已经发布的版本,是没法在给接口添加新方法的同时不影响已有的实现。所以引进的默认方法。他们的目的是为了解决接口的修改与现有的实现不兼容的问题。

语法

默认方法语法格式如下:

  1. public interface Vehicle {
  2. default void print(){
  3. System.out.println("我是一辆车!");
  4. }
  5. }

多个默认方法

一个接口有默认方法,考虑这样的情况,一个类实现了多个接口,且这些接口有相同的默认方法,以下实例说明了这种情况的解决方法:

  1. public interface Vehicle {
  2. default void print(){
  3. System.out.println("我是一辆车!");
  4. }
  5. }
  6. public interface FourWheeler {
  7. default void print(){
  8. System.out.println("我是一辆四轮车!");
  9. }
  10. }

第一个解决方案是创建自己的默认方法,来覆盖重写接口的默认方法:

  1. public class Car implements Vehicle, FourWheeler {
  2. default void print(){
  3. System.out.println("我是一辆四轮汽车!");
  4. }
  5. }

第二种解决方案可以使用 super 来调用指定接口的默认方法:

  1. public class Car implements Vehicle, FourWheeler {
  2. public void print(){
  3. Vehicle.super.print();
  4. }
  5. }

静态默认方法

Java 8 的另一个特性是接口可以声明(并且可以提供实现)静态方法。例如:

  1. public interface Vehicle {
  2. default void print(){
  3. System.out.println("我是一辆车!");
  4. }
  5. // 静态方法
  6. static void blowHorn(){
  7. System.out.println("按喇叭!!!");
  8. }
  9. }

默认方法实例

我们可以通过以下代码来了解关于默认方法的使用,可以将代码放入 Java8Tester.java 文件中:

  1. public class Java8Tester {
  2. public static void main(String args[]){
  3. Vehicle vehicle = new Car();
  4. vehicle.print();
  5. }
  6. }
  7. interface Vehicle {
  8. default void print(){
  9. System.out.println("我是一辆车!");
  10. }
  11. static void blowHorn(){
  12. System.out.println("按喇叭!!!");
  13. }
  14. }
  15. interface FourWheeler {
  16. default void print(){
  17. System.out.println("我是一辆四轮车!");
  18. }
  19. }
  20. class Car implements Vehicle, FourWheeler {
  21. public void print(){
  22. Vehicle.super.print();
  23. FourWheeler.super.print();
  24. Vehicle.blowHorn();
  25. System.out.println("我是一辆汽车!");
  26. }
  27. }

Java 8 Stream

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

1649138593(1).png
以上的流程转换为 Java 代码为:

  1. List<Integer> transactionsIds =
  2. widgets.stream()
  3. .filter(b -> b.getColor() == RED)
  4. .sorted((x,y) -> x.getWeight() - y.getWeight())
  5. .mapToInt(Widget::getWeight)
  6. .sum();

什么是 Stream?

Stream(流)是一个来自数据源的元素队列并支持聚合操作

  • 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
  • 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
  • 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。

和以前的Collection操作不同, Stream操作还有两个基础的特征:

  • Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
  • 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

    生成流

    在 Java 8 中, 集合接口有两个方法来生成流:

  • stream() − 为集合创建串行流。

  • parallelStream() − 为集合创建并行流。
    1. List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
    2. List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

    forEach

    Stream 提供了新的方法 ‘forEach’ 来迭代流中的每个数据。以下代码片段使用 forEach 输出了10个随机数:
    1. Random random = new Random();
    2. random.ints().limit(10).forEach(System.out::println);

    map

    map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数:
    1. List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
    2. // 获取对应的平方数
    3. List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

    filter

    filter 方法用于通过设置的条件过滤出元素。以下代码片段使用 filter 方法过滤出空字符串:
    1. List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
    2. // 获取空字符串的数量
    3. long count = strings.stream().filter(string -> string.isEmpty()).count();

    limit

    limit 方法用于获取指定数量的流。 以下代码片段使用 limit 方法打印出 10 条数据:
    1. Random random = new Random();
    2. random.ints().limit(10).forEach(System.out::println);

    sorted

    sorted 方法用于对流进行排序。以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序:
    1. Random random = new Random();
    2. random.ints().limit(10).sorted().forEach(System.out::println);

    并行(parallel)程序

    parallelStream 是流并行处理程序的代替方法。以下实例我们使用 parallelStream 来输出空字符串的数量:
    1. List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
    2. // 获取空字符串的数量
    3. long count = strings.parallelStream().filter(string -> string.isEmpty()).count();
    我们可以很容易的在顺序运行和并行直接切换。

    Collectors

    Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串: ```java Liststrings = Arrays.asList(“abc”, “”, “bc”, “efg”, “abcd”,””, “jkl”); List filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

System.out.println(“筛选列表: “ + filtered); String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(“, “)); System.out.println(“合并字符串: “ + mergedString);

  1. <a name="IzxYw"></a>
  2. ## 统计
  3. 另外,一些产生统计结果的收集器也非常有用。它们主要用于int、double、long等基本类型上,它们可以用来产生类似如下的统计结果。
  4. ```java
  5. List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
  6. IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
  7. System.out.println("列表中最大的数 : " + stats.getMax());
  8. System.out.println("列表中最小的数 : " + stats.getMin());
  9. System.out.println("所有数之和 : " + stats.getSum());
  10. System.out.println("平均数 : " + stats.getAverage());

Stream 完整实例

将以下代码放入 Java8Tester.java 文件中:

  1. import java.util.ArrayList;
  2. import java.util.Arrays;
  3. import java.util.IntSummaryStatistics;
  4. import java.util.List;
  5. import java.util.Random;
  6. import java.util.stream.Collectors;
  7. import java.util.Map;
  8. public class Java8Tester {
  9. public static void main(String args[]){
  10. System.out.println("使用 Java 7: ");
  11. // 计算空字符串
  12. List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
  13. System.out.println("列表: " +strings);
  14. long count = getCountEmptyStringUsingJava7(strings);
  15. System.out.println("空字符数量为: " + count);
  16. count = getCountLength3UsingJava7(strings);
  17. System.out.println("字符串长度为 3 的数量为: " + count);
  18. // 删除空字符串
  19. List<String> filtered = deleteEmptyStringsUsingJava7(strings);
  20. System.out.println("筛选后的列表: " + filtered);
  21. // 删除空字符串,并使用逗号把它们合并起来
  22. String mergedString = getMergedStringUsingJava7(strings,", ");
  23. System.out.println("合并字符串: " + mergedString);
  24. List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
  25. // 获取列表元素平方数
  26. List<Integer> squaresList = getSquares(numbers);
  27. System.out.println("平方数列表: " + squaresList);
  28. List<Integer> integers = Arrays.asList(1,2,13,4,15,6,17,8,19);
  29. System.out.println("列表: " +integers);
  30. System.out.println("列表中最大的数 : " + getMax(integers));
  31. System.out.println("列表中最小的数 : " + getMin(integers));
  32. System.out.println("所有数之和 : " + getSum(integers));
  33. System.out.println("平均数 : " + getAverage(integers));
  34. System.out.println("随机数: ");
  35. // 输出10个随机数
  36. Random random = new Random();
  37. for(int i=0; i < 10; i++){
  38. System.out.println(random.nextInt());
  39. }
  40. System.out.println("使用 Java 8: ");
  41. System.out.println("列表: " +strings);
  42. count = strings.stream().filter(string->string.isEmpty()).count();
  43. System.out.println("空字符串数量为: " + count);
  44. count = strings.stream().filter(string -> string.length() == 3).count();
  45. System.out.println("字符串长度为 3 的数量为: " + count);
  46. filtered = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.toList());
  47. System.out.println("筛选后的列表: " + filtered);
  48. mergedString = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.joining(", "));
  49. System.out.println("合并字符串: " + mergedString);
  50. squaresList = numbers.stream().map( i ->i*i).distinct().collect(Collectors.toList());
  51. System.out.println("Squares List: " + squaresList);
  52. System.out.println("列表: " +integers);
  53. IntSummaryStatistics stats = integers.stream().mapToInt((x) ->x).summaryStatistics();
  54. System.out.println("列表中最大的数 : " + stats.getMax());
  55. System.out.println("列表中最小的数 : " + stats.getMin());
  56. System.out.println("所有数之和 : " + stats.getSum());
  57. System.out.println("平均数 : " + stats.getAverage());
  58. System.out.println("随机数: ");
  59. random.ints().limit(10).sorted().forEach(System.out::println);
  60. // 并行处理
  61. count = strings.parallelStream().filter(string -> string.isEmpty()).count();
  62. System.out.println("空字符串的数量为: " + count);
  63. }
  64. private static int getCountEmptyStringUsingJava7(List<String> strings){
  65. int count = 0;
  66. for(String string: strings){
  67. if(string.isEmpty()){
  68. count++;
  69. }
  70. }
  71. return count;
  72. }
  73. private static int getCountLength3UsingJava7(List<String> strings){
  74. int count = 0;
  75. for(String string: strings){
  76. if(string.length() == 3){
  77. count++;
  78. }
  79. }
  80. return count;
  81. }
  82. private static List<String> deleteEmptyStringsUsingJava7(List<String> strings){
  83. List<String> filteredList = new ArrayList<String>();
  84. for(String string: strings){
  85. if(!string.isEmpty()){
  86. filteredList.add(string);
  87. }
  88. }
  89. return filteredList;
  90. }
  91. private static String getMergedStringUsingJava7(List<String> strings, String separator){
  92. StringBuilder stringBuilder = new StringBuilder();
  93. for(String string: strings){
  94. if(!string.isEmpty()){
  95. stringBuilder.append(string);
  96. stringBuilder.append(separator);
  97. }
  98. }
  99. String mergedString = stringBuilder.toString();
  100. return mergedString.substring(0, mergedString.length()-2);
  101. }
  102. private static List<Integer> getSquares(List<Integer> numbers){
  103. List<Integer> squaresList = new ArrayList<Integer>();
  104. for(Integer number: numbers){
  105. Integer square = new Integer(number.intValue() * number.intValue());
  106. if(!squaresList.contains(square)){
  107. squaresList.add(square);
  108. }
  109. }
  110. return squaresList;
  111. }
  112. private static int getMax(List<Integer> numbers){
  113. int max = numbers.get(0);
  114. for(int i=1;i < numbers.size();i++){
  115. Integer number = numbers.get(i);
  116. if(number.intValue() > max){
  117. max = number.intValue();
  118. }
  119. }
  120. return max;
  121. }
  122. private static int getMin(List<Integer> numbers){
  123. int min = numbers.get(0);
  124. for(int i=1;i < numbers.size();i++){
  125. Integer number = numbers.get(i);
  126. if(number.intValue() < min){
  127. min = number.intValue();
  128. }
  129. }
  130. return min;
  131. }
  132. private static int getSum(List numbers){
  133. int sum = (int)(numbers.get(0));
  134. for(int i=1;i < numbers.size();i++){
  135. sum += (int)numbers.get(i);
  136. }
  137. return sum;
  138. }
  139. private static int getAverage(List<Integer> numbers){
  140. return getSum(numbers) / numbers.size();
  141. }
  142. }

.

Java 8 Optional 类

Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
Optional 类的引入很好的解决空指针异常。

类声明

以下是一个 java.util.Optional 类的声明:

  1. public final class Optional<T>
  2. extends Object

类方法

序号 方法 & 描述
1 static Optional empty()
返回空的 Optional 实例。
2 boolean equals(Object obj)
判断其他对象是否等于 Optional。
3 Optional filter(Predicate<? super predicate)
如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional。
4 Optional flatMap(Function<? super T,Optional> mapper)
如果值存在,返回基于Optional包含的映射方法的值,否则返回一个空的Optional
5 T get()
如果在这个Optional中包含这个值,返回值,否则抛出异常:NoSuchElementException
6 int hashCode()
返回存在值的哈希码,如果值不存在 返回 0。
7 void ifPresent(Consumer<? super T> consumer)
如果值存在则使用该值调用 consumer , 否则不做任何事情。
8 boolean isPresent()
如果值存在则方法会返回true,否则返回 false。
9 Optional map(Function<? super T,? extends U> mapper)
如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值,否则返回空Optional。
10 static Optional of(T value)
返回一个指定非null值的Optional。
11 static Optional ofNullable(T value)
如果为非空,返回 Optional 描述的指定值,否则返回空的 Optional。
12 T orElse(T other)
如果存在该值,返回值, 否则返回 other。
13 T orElseGet(Supplier<? extends T> other)
如果存在该值,返回值, 否则触发 other,并返回 other 调用的结果。
14 T orElseThrow(Supplier<? extends X> exceptionSupplier)
如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常
15 String toString()
返回一个Optional的非空字符串,用来调试

注意: 这些方法是从 java.lang.Object 类继承来的。

Optional 实例

我们可以通过以下实例来更好的了解 Optional 类的使用:

  1. import java.util.Optional;
  2. public class Java8Tester {
  3. public static void main(String args[]){
  4. Java8Tester java8Tester = new Java8Tester();
  5. Integer value1 = null;
  6. Integer value2 = new Integer(10);
  7. // Optional.ofNullable - 允许传递为 null 参数
  8. Optional<Integer> a = Optional.ofNullable(value1);
  9. // Optional.of - 如果传递的参数是 null,抛出异常 NullPointerException
  10. Optional<Integer> b = Optional.of(value2);
  11. System.out.println(java8Tester.sum(a,b));
  12. }
  13. public Integer sum(Optional<Integer> a, Optional<Integer> b){
  14. // Optional.isPresent - 判断值是否存在
  15. System.out.println("第一个参数值存在: " + a.isPresent());
  16. System.out.println("第二个参数值存在: " + b.isPresent());
  17. // Optional.orElse - 如果值存在,返回它,否则返回默认值
  18. Integer value1 = a.orElse(new Integer(0));
  19. //Optional.get - 获取值,值需要存在
  20. Integer value2 = b.get();
  21. return value1 + value2;
  22. }
  23. }

Java 8 日期时间 API

Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。
在旧版的 Java 中,日期时间 API 存在诸多问题,其中有:

  • 非线程安全 − java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。
  • 设计很差 − Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义。java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。
  • 时区处理麻烦 − 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。

Java 8 在 java.time 包下提供了很多新的 API。以下为两个比较重要的 API:

  • Local(本地) − 简化了日期时间的处理,没有时区的问题。
  • Zoned(时区) − 通过制定的时区处理日期时间。

新的java.time包涵盖了所有处理日期,时间,日期/时间,时区,时刻(instants),过程(during)与时钟(clock)的操作。

本地化日期时间 API

LocalDate/LocalTime 和 LocalDateTime 类可以在处理时区不是必须的情况。代码如下:

  1. import java.time.LocalDate;
  2. import java.time.LocalTime;
  3. import java.time.LocalDateTime;
  4. import java.time.Month;
  5. public class Java8Tester {
  6. public static void main(String args[]){
  7. Java8Tester java8tester = new Java8Tester();
  8. java8tester.testLocalDateTime();
  9. }
  10. public void testLocalDateTime(){
  11. // 获取当前的日期时间
  12. LocalDateTime currentTime = LocalDateTime.now();
  13. System.out.println("当前时间: " + currentTime);
  14. LocalDate date1 = currentTime.toLocalDate();
  15. System.out.println("date1: " + date1);
  16. Month month = currentTime.getMonth();
  17. int day = currentTime.getDayOfMonth();
  18. int seconds = currentTime.getSecond();
  19. System.out.println("月: " + month +", 日: " + day +", 秒: " + seconds);
  20. LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012);
  21. System.out.println("date2: " + date2);
  22. // 12 december 2014
  23. LocalDate date3 = LocalDate.of(2014, Month.DECEMBER, 12);
  24. System.out.println("date3: " + date3);
  25. // 22 小时 15 分钟
  26. LocalTime date4 = LocalTime.of(22, 15);
  27. System.out.println("date4: " + date4);
  28. // 解析字符串
  29. LocalTime date5 = LocalTime.parse("20:15:30");
  30. System.out.println("date5: " + date5);
  31. }
  32. }

使用时区的日期时间API

如果我们需要考虑到时区,就可以使用时区的日期时间API:

  1. import java.time.ZonedDateTime;
  2. import java.time.ZoneId;
  3. public class Java8Tester {
  4. public static void main(String args[]){
  5. Java8Tester java8tester = new Java8Tester();
  6. java8tester.testZonedDateTime();
  7. }
  8. public void testZonedDateTime(){
  9. // 获取当前时间日期
  10. ZonedDateTime date1 = ZonedDateTime.parse("2015-12-03T10:15:30+05:30[Asia/Shanghai]");
  11. System.out.println("date1: " + date1);
  12. ZoneId id = ZoneId.of("Europe/Paris");
  13. System.out.println("ZoneId: " + id);
  14. ZoneId currentZone = ZoneId.systemDefault();
  15. System.out.println("当期时区: " + currentZone);
  16. }
  17. }