Java 8 | 简介

Java 10 都已经出来了,为啥还在学 Java 8 呢?

首先是我自己没有系统的学习 Java 8 的新特性,只是看博客的时候学到那些是那些。

其次呢,2017年9月,Oracle 将 Java 大版本周期从原来的 2-3 年,调整成每半年发布一个大的版本。而版本号仍延续原来的序号,即 Java 8、Java 9、Java 10、Java 11.....

但和之前不一样的是,同时还有一个版本号来表示发布的时间和是否为 LTS(长期支持版本),比如 Java 10 对应 18.3。如下示例:

/jdk-10/bin$ ./java -version

openjdk version "10" 2018-03-20

OpenJDK Runtime Environment 18.3 (build 10+46)

OpenJDK 64-Bit Server VM 18.3 (build 10+46, mixed mode)

需要注意的是 Java 9 和 Java 10 都不是 LTS 版本。和过去的 Java 大版本升级不同,这两个只有半年左右的开发和维护期。而未来的 Java 11,也就是 18.9 LTS,才是 Java 8 之后第一个 LTS 版本(得到 Oracle 等商业公司的长期支持服务)。

所以等 Java 11 出来了再去学习新的特征也不迟,不过尝鲜的小伙伴可以了解一下 Java 9 和 Java 10 添加了那些特征。这里我还是老老实实啃一下 Java 8 吧。

Java 8中我们谈论最多的就是 lambda 表达式了,当然它还有其他的特性,比如 默认方法,stream API 和 新的 Date/Time API 等等。下面我们先用例子来了解一下 Java 8 的一下特性吧。

Lambda 表达式

在编程使用上,Lambda 表达式就像是匿名函数一样,我们将Lambda 表达式当做一个参数传递给另一个函数,是不是很神奇。但是这个特性在 Scala 中已经很常见了。

Lambda 表达式的基本语法

(parameters) -> expression
或者
(parameters) -> { statements; }
或者
() -> expression

举个例子

(x, y) -> x + y // 这个函数接受2个参数,并且返回2个参数的和

书写 Lambda 表达式的规则

  1. 一个 Lambda 表达式可以有 0个,1个或者更多的参数。
  2. 参数的类型可以显示声明出来,也可以通过代码推断出来参数的类型。
  3. 多个参数必须放在 () 中并用 , 分隔 比如这样 (param1, param2, param3),空的() 表示不接受任何参数。
  4. 当只有一个参数的时候,如果参数类型能够被推断出来,可以不必使用(),比如 a -> a * a。
  5. lambda 书写语句部分能够有 0条,1条或多条语句。
  6. 当 lambda 书写语句部分只有1条语句时,可以不用书写 {},并且这个匿名函数的返回值就是表达式语句的结果。当书写语句部分不止1条语句时必须使用 {} 将这些语句包裹进来。

函数接口

函数接口也称为 Single Abstract Method interfaces (SAM Interfaces)。从名字可以看出,这种接口只允许有1个抽象方法。Java 8 提供了 @FunctionalInterface 注解,当使用这个注解标识一个接口的时候,这个接口如果不符合函数接口的规定,编译器会报错。

举个例子

@FunctionalInterface
public interface MyFirstFunctionalInterface {
    public void firstWork();
}

注意,即使忽略@FunctionalInterface注释,函数接口也是有效的。 它仅用于通知编译器在接口内强制执行单一抽象方法。

因为默认方法不是抽象方法,所以可以在函数接口中任意添加默认方法(你开心就好)。

另外需要注意,一个接口声明了一个抽象方法重载了 java.lang.Object 类中的 public 方法,这个方法不算作接口的抽象方法,因为这个接口的任何实现都会有这些方法(Object 中声明的 public 方法)的实现,这些实现可能来自于 java.lang.Object 或其他类。例如下面这个函数接口任然合理。

@FunctionalInterface
public interface MyFirstFunctionalInterface{
    public void firstWork();
 
    @Override
    public String toString();                //Overridden from Object class
 
    @Override
    public boolean equals(Object obj);        //Overridden from Object class
}

默认方法

Java 8 允许在接口中添加非抽象的方法。这些方法必须声明为默认方法。在 Java 8 中引入了默认方法来启用 lambda 表达式的功能。

默认方法使您可以向库的接口添加新功能,并确保与为这些接口的旧版本编写的代码的二进制兼容性。最典型的例子就是 Java 8 中的 List 接口。

举个例子

public interface Moveable {
    default void move(){
       log.info("I am moving");
    }
}

Moveable 接口定义了move()方法并提供了 move() 方法的默认实现,如果任何类实现了 Moveable 这个接口,这个类不必实现 move() 方法,可以直接调用 instance.move() 方法。

public class Animal implements Moveable {
    public static void main(String[] args){
        Animal tiger = new Animal();
        tiger.move();
    }
}
  
Output: I am moving

如果类想要自己实现 move() 方法也可以重载这个方法。

Streams

另外一个主要改变就是 Java 8 的 Streams API,Stream API 提供了对数据集处理的一种机制,可以对数据集进行过滤、转换或者对应用程序可能有用的任何其他方式。

举例说明, items 是 String 的集合,我们移除其中一些以某些前缀开始的项。

List<String> items;
String prefix;
List<String> filteredList = items.stream().filter(e -> (!e.startsWith(prefix))).collect(Collectors.toList());

items.stream() 表示我们希望使用 Stream API 来处理这个集合。

Date/Time API 的变化

Dates

Date 类已经过时啦,在 Java 8 中使用 LocalDate, LocalTime and LocalDateTime 来替代原来的 Date 类。

  1. LocalDate 代表日期。没有时间或时区的含义。
  2. LocalTime 掉代表时间。没有日期或时区的含义。
  3. LocalDateTime 代表 日期和时间。没有时区的含义。

如果想使用日期并且带上时区的信息, Lambda 提供可另外 3 个相似的类 OffsetDate, OffsetTime and OffsetDateTime。时区可以用 “+05:30” 或者 “Europe/Paris” 代表。可以使用 ZoneId 来完成。

LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.of(12, 20);
LocalDateTime localDateTime = LocalDateTime.now();
OffsetDateTime offsetDateTime = OffsetDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Paris"));

====
输出
12:20
2018-04-12T22:21:01.597
2018-04-12T22:21:01.598+08:00
2018-04-12T16:21:01.601+02:00[Europe/Paris]

Timestamp and Duration

为了随时表示特定时间戳,需要使用 Instant 类。Instant 类表示一个瞬时,精度精确到了纳秒。 可以在 Instant 上进行加或减一段时间生成一个新的 Instant 类。

Instant instant = Instant.now();
Instant instant1 = instant.plus(Duration.ofMillis(5000));
Instant instant2 = instant.minus(Duration.ofMillis(5000));
Instant instant3 = instant.minusSeconds(10);

Duration 类是 Java 语言中首次引入的全新概念。 它表示两个时间戳之间的时间差。

Duration duration = Duration.ofMillis(5000);
duration = Duration.ofSeconds(60);
duration = Duration.ofMinutes(10);

Duration 类适合处理诸如毫秒,秒,分钟和小时等小单位时间,这更世界与程序代码交互,如果想与人类进行交互,最好使用更大的时间单位,这是可以使用 Period 类来代表。

Period period = Period.ofDays(6);
period = Period.ofMonths(6);
period = Period.between(LocalDate.now(), LocalDate.now().plusDays(60));
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容