JDK1.8新增语法

JDK 1.8(Java 8)是 Java 历史上的里程碑版本,引入了大量改变开发模式的新语法和特性,核心聚焦于函数式编程简化代码

一、核心:Lambda 表达式(函数式编程基础)

Lambda 表达式是 JDK8 最核心的语法升级,用于简化函数式接口(仅含一个抽象方法的接口)的匿名内部类实现,本质是 "可传递的代码块"。

语法格式

bash 复制代码
(参数列表) -> { 执行语句; }
// 简化规则:
// 1. 单参数可省略括号:param -> { ... }
// 2. 单执行语句可省略大括号和分号:param -> statement
// 3. 有返回值且单语句可省略return:param -> expression

示例:替代匿名内部类

java 复制代码
// 传统匿名内部类(Runnable接口)
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("传统方式");
    }
}).start();

// Lambda简化
new Thread(() -> System.out.println("Lambda方式")).start();

// 示例2:Comparator排序(简化多参数场景)
List<String> list = Arrays.asList("b", "a", "c");
// 传统方式
Collections.sort(list, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o1.compareTo(o2);
    }
});
// Lambda简化
Collections.sort(list, (o1, o2) -> o1.compareTo(o2));

二、函数式接口(Lambda 的载体)

JDK8 正式定义 "函数式接口":仅包含一个抽象方法 的接口(可含默认方法 / 静态方法),并提供@FunctionalInterface注解校验(非强制,但推荐使用)。

核心特性

  • 注解@FunctionalInterface:编译期校验接口是否符合函数式规范;
  • JDK8 内置了大量常用函数式接口(位于java.util.function包),避免重复定义:
接口 抽象方法 用途 示例
Consumer<T> accept(T t) 消费型(入参无返回) list.forEach(s -> System.out.println(s))
Supplier<T> get() 供给型(无入参有返回) () -> new ArrayList<>()
Function<T,R> apply(T t) 函数型(入参 T 返回 R) s -> s.length()
Predicate<T> test(T t) 断言型(入参返回布尔) s -> s.isEmpty()

示例:使用内置函数式接口

java 复制代码
// Predicate:过滤空字符串
Predicate<String> isEmpty = s -> s.isEmpty();
System.out.println(isEmpty.test("")); // true

// Function:字符串转长度
Function<String, Integer> strLength = s -> s.length();
System.out.println(strLength.apply("Java8")); // 5

三、方法引用(Lambda 的简化版)

方法引用是 Lambda 的语法糖,当 Lambda 体仅调用一个已存在的方法时,可进一步简化代码,格式为类名/对象::方法名

java 复制代码
wrapper.like(StringUtils.isNotBlank(username),User::getName,"a")
                .gt(ageBegin != null,User::getAge,ageBegin)
                .lt(ageEnd != null,User::getAge,ageEnd);

四种类型的方法引用

类型 语法示例 对应 Lambda
静态方法引用 类名::静态方法 (a,b) -> 类名.静态方法(a,b)
实例方法引用(任意对象) 类名::实例方法 (obj, a) -> obj.实例方法(a)
实例方法引用(特定对象) 对象::实例方法 (a) -> 对象.实例方法(a)
构造器引用 类名::new () -> new 类名()

示例

java 复制代码
// 1. 静态方法引用:Integer::parseInt 等价于 s -> Integer.parseInt(s)
Function<String, Integer> f1 = Integer::parseInt;
System.out.println(f1.apply("123")); // 123

// 2. 特定对象的实例方法引用:System.out::println 等价于 s -> System.out.println(s)
Consumer<String> f2 = System.out::println;
f2.accept("方法引用示例");

// 3. 构造器引用:ArrayList::new 等价于 () -> new ArrayList<>()
Supplier<List<String>> f3 = ArrayList::new;
List<String> list = f3.get();

四、接口的默认方法(default)和静态方法(static)

JDK8 前,接口只能包含抽象方法;JDK8 允许接口定义:

  • 默认方法default):带方法体的实例方法,子类可重写,解决 "接口升级兼容问题";
  • 静态方法static):带方法体的静态方法,通过接口名直接调用。
java 复制代码
public interface MyInterface {
    // 抽象方法(必须实现)
    void abstractMethod();

    // 默认方法(子类可继承/重写)
    default void defaultMethod() {
        System.out.println("接口默认方法");
    }

    // 静态方法(接口名调用)
    static void staticMethod() {
        System.out.println("接口静态方法");
    }
}

// 实现类
class MyImpl implements MyInterface {
    @Override
    public void abstractMethod() {
        System.out.println("实现抽象方法");
    }
    // 可选重写默认方法
    @Override
    public void defaultMethod() {
        System.out.println("重写默认方法");
    }
}

// 调用
MyInterface.staticMethod(); // 接口静态方法
MyImpl impl = new MyImpl();
impl.defaultMethod(); // 重写默认方法

五、Stream API(集合流式处理)

Stream API 是 JDK8 为集合提供的函数式流式处理语法,支持链式操作、并行处理,简化集合遍历 / 过滤 / 映射等操作(类似 SQL 的声明式语法)。

核心特性

  • 流式操作:分为 "中间操作"(延迟执行,返回 Stream)和 "终止操作"(立即执行,返回结果);
  • 无状态 / 有状态:中间操作分为无状态(filter/map)和有状态(sorted/distinct);
  • 并行流 :利用多核 CPU,通过parallel()切换并行处理。

语法示例:链式操作

java 复制代码
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);

// 需求:过滤偶数 → 乘以2 → 求和
int sum = nums.stream()
              .filter(n -> n % 2 == 0) // 中间操作:过滤偶数
              .map(n -> n * 2)         // 中间操作:映射乘2
              .reduce(0, Integer::sum); // 终止操作:求和
System.out.println(sum); // (2+4+6+8)*2 = 40

// 并行流(适合大数据量)
int parallelSum = nums.parallelStream()
                      .filter(n -> n % 2 == 0)
                      .mapToInt(n -> n * 2)
                      .sum();

六、Optional 类(解决空指针 NPE)

Optional 是 JDK8 提供的 "空安全" 容器,封装可能为null的对象,强制开发者处理空值,避免直接判空(if (obj == null))。

核心方法

方法 用途
Optional.of(T) 创建非空 Optional(null 则抛 NPE)
Optional.ofNullable(T) 创建可空 Optional
ifPresent(Consumer) 非空时执行消费逻辑
orElse(T) 空时返回默认值
orElseGet(Supplier) 空时通过 Supplier 生成默认值
orElseThrow(Supplier) 空时抛自定义异常

示例

java 复制代码
// 传统空判(易漏判)
String str = null;
if (str != null) {
    System.out.println(str.length());
}

// Optional简化
Optional<String> opt = Optional.ofNullable(str);
opt.ifPresent(s -> System.out.println(s.length())); // 非空才执行
String defaultStr = opt.orElse("默认值"); // 空则返回默认值
String defaultStr2 = opt.orElseGet(() -> "动态生成默认值");
opt.orElseThrow(() -> new IllegalArgumentException("值不能为空"));

七、新日期时间 API(JSR 310)

替代旧的Date/Calendar(线程不安全、设计混乱),提供不可变、线程安全 的日期时间处理类,位于java.time包。

核心类

用途 示例
LocalDate 本地日期(年 / 月 / 日) LocalDate.now() → 2025-11-29
LocalTime 本地时间(时 / 分 / 秒) LocalTime.now() → 10:30:00
LocalDateTime 本地日期时间 LocalDateTime.now()
Instant 时间戳(UTC) Instant.now()
Duration 时间间隔(秒 / 纳秒) Duration.between(t1, t2)
Period 日期间隔(年 / 月 / 日) Period.between(d1, d2)
DateTimeFormatter 日期格式化(替代 SimpleDateFormat) DateTimeFormatter.ofPattern("yyyy-MM-dd")

示例

java 复制代码
// 1. 获取当前日期时间
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // 2025-11-29T10:35:20.123

// 2. 格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatStr = now.format(formatter);
System.out.println(formatStr); // 2025-11-29 10:35:20

// 3. 时间计算
LocalDateTime tomorrow = now.plusDays(1); // 加1天
LocalDateTime lastMonth = now.minusMonths(1); // 减1月

// 4. 解析字符串
LocalDate date = LocalDate.parse("2025-12-01", formatter);

八、其他次要语法 / 特性

重复注解(@Repeatable)

允许同一注解在同一位置多次使用,解决旧版本注解只能用一次的问题:

java 复制代码
@Repeatable(Roles.class) // 声明可重复
@interface Role { String value(); }
@interface Roles { Role[] value(); }

// 使用
@Role("admin")
@Role("user")
public class User {}

类型注解

注解可用于任意类型上下文(如泛型、数组、方法参数类型等),配合静态检查工具(如 FindBugs)提升代码安全性:

java 复制代码
// 泛型类型注解
List<@NonNull String> list = new ArrayList<>();
// 数组类型注解
String @NonNull [] arr = new String[10];

Base64 内置支持

新增java.util.Base64类,替代第三方 Base64 库(如 Apache Commons),支持标准 / URL 安全 / MIME 编码:

java 复制代码
String str = "Java8";
// 编码
String encode = Base64.getEncoder().encodeToString(str.getBytes());
// 解码
byte[] decode = Base64.getDecoder().decode(encode);
System.out.println(new String(decode)); // Java8
相关推荐
心随雨下43 分钟前
TypeScript泛型开发常见错误解析
java·开发语言·typescript
DonaldCen6661 小时前
Java 王者修炼手册【Mysql篇 - SQL执行存储流程】:拆解 InnoDB 存储结构与 SQL 执行流程,吃透 Buffer Pool 和 Change
java
旺仔Sec1 小时前
2025年广东省职业院校技能大赛高职组“区块链技术应用”竞赛试题(二)
java·区块链
郝学胜-神的一滴1 小时前
现代OpenGL窗口管理:GLFW从入门到实战
开发语言·c++·程序人生·图形渲染·个人开发
Boop_wu1 小时前
[Java EE] 多线程编程进阶
java·数据库·java-ee
w***37512 小时前
SpringBoot【实用篇】- 测试
java·spring boot·后端
谁刺我心2 小时前
C++三种智能指针unique、shared、weak
开发语言·c++
q***61412 小时前
Java实战:Spring Boot实现WebSocket实时通信
java·spring boot·websocket
k***82512 小时前
Ubuntu介绍、与centos的区别、基于VMware安装Ubuntu Server 22.04、配置远程连接、安装jdk+Tomcat
java·ubuntu·centos