Java新特性全面解析
一、Lambda表达式:让代码更简洁
1.1从匿名类到Lambda表达式
还记得以前写匿名内部类的痛苦吗?
// Java 7写法
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("按钮被点击了");
}
});
Lambda表达式简化写法:
// Java 8写法
button.addActionListener(e -> System.out.println("按钮被点击了"));
1.2方法引用:更简洁的表达
传统Lambda表达:
list.forEach(x -> System.out.println(x));
方法引用简化:
list.forEach(System.out::println);
方法引用四大类型:
ClassName::staticMethod静态方法引用instance::method实例方法引用ClassName::instanceMethod任意对象方法引用ClassName::new构造方法引用
二、Stream API:数据处理新方式
2.1从循环到Stream
int sum = 0;
for(int num : numbers) {
if(num % 2 == 0) {
sum += num;
}
}
Stream处理方式:
int sum = numbers.stream()
.filter(n -> n % 2 == 0)
.mapToInt(Integer::intValue)
.sum();
2.2 常用Stream操作
| 类型 | 方法示例 | 说明 |
|---|---|---|
| 中间操作 | filter(), map(), sorted() | 返回新Stream |
| 终端操作 | forEach(), collect(), reduce() | 产生最终结果 |
并行流使用示例:
// 顺序流
list.stream().filter(...).count();
// 并行流
list.parallelStream().filter(...).count();
三、Optional:优雅处理null
3.1 告别NullPointerException
传统null检查:
public String getUserName(User user) {
if(user != null) {
return user.getName();
}
return "未知用户";
}
Optional优化写法:
public String getUserName(User user) {
return Optional.ofNullable(user)
.map(User::getName)
.orElse("未知用户");
}
3.2 Optional实用方法
Optional.ofNullable(value)
.filter(v -> v.length() > 3) // 过滤
.map(String::toUpperCase) // 转换
.orElseGet(() -> defaultValue); // 默认值
四、新日期API:终于好用的时间处理
4.1 对比新旧API
// 老API(容易出错)
Calendar cal = Calendar.getInstance();
cal.set(2023, Calendar.JULY, 20); // 月份从0开始!
// 新API(直观清晰)
LocalDate date = LocalDate.of(2023, Month.JULY, 20);
4.2 主要类介绍
| 类名 | 用途 | 示例 |
|---|---|---|
| LocalDate | 只含日期 | 2023-07-20 |
| LocalTime | 只含时间 | 14:30:00 |
| LocalDateTime | 日期+时间 | 2023-07-20T14:30 |
| Duration | 时间间隔 | 计算两个时间点差值 |
| Period | 日期间隔 | 计算两个日期差值 |
计算示例:
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1990, Month.JANUARY, 1);
Period period = Period.between(birthday, today);
System.out.println("年龄:" + period.getYears() + "岁");
五、模块化系统(JPMS):告别JAR地狱
5.1 什么是模块化
// module-info.java
module com.myapp {
requires java.base; // 依赖基础模块
requires java.sql; // 需要SQL模块
exports com.myapp.api; // 暴露的包
}
5.2 主要优势
- 强封装性:明确控制哪些包可被外部访问
- 可靠配置:启动时检查模块依赖
- 更小的运行时:只包含需要的模块
常用命令:
# 编译模块
javac -d out --module-source-path src --module com.myapp
# 运行模块
java --module-path out -m com.myapp/com.myapp.Main
六、其他实用新特性
6.1 var局部变量类型推断(Java 10+)
// 以前
Map<String, List<Employee>> map = new HashMap<>();
// 现在
var map = new HashMap<String, List<Employee>>();
6.2 文本块(Java 15+)
// 传统方式
String html = "<html>\n" +
" <body>\n" +
" <p>Hello</p>\n" +
" </body>\n" +
"</html>";
// 文本块
String html = """
<html>
<body>
<p>Hello</p>
</body>
</html>""";
6.3 record记录类(Java 16+)
// 替代传统的POJO
public record Employee(String name, int id, Department dept) {}
// 自动生成:
// 1. 全参构造方法
// 2. getter方法(name()而不是getName())
// 3. equals()/hashCode()/toString()
七、如何选择Java版本
| 版本 | 发布时间 | 长期支持(LTS) | 推荐使用场景 |
|---|---|---|---|
| Java 8 | 2014 | 是 | 传统企业应用 |
| Java 11 | 2018 | 是 | 大多数新项目 |
| Java 17 | 2021 | 是 | 追求最新特性 |
升级建议:
- 新项目直接使用Java 17
- 已有项目逐步从8迁移到11再到17
- 关注每半年发布的非LTS版本中的新特性
八、实战建议
- 渐进式采用:不必一次性全部使用新特性
- 团队共识:制定统一的代码规范
- IDE支持:使用IntelliJ IDEA等现代IDE获得最佳支持
- 性能测试:特别是Stream并行流要实测效果
记住:使用新特性的目的是写出更简洁、更安全的代码,而不是为了炫技。选择适合你团队和项目的特性,逐步引入,才能真正发挥它们的价值。