Oracle JDK 8引入了一些重要的新特性,以下是其中一些主要的特性以及详细的例子:
Lambda 表达式允许在不创建单独方法的情况下直接以更紧凑的方式编写匿名函数。这对于函数式编程非常有用。
// 旧的方式:使用匿名内部类
Runnable oldRunnable = new Runnable() {
@Override
public void run() {
System.out.println("Old way of running a Runnable");
}
};
// 使用 Lambda 表达式
Runnable newRunnable = () -> System.out.println("New way of running a Runnable");
// 在集合上使用 Lambda 表达式
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name -> System.out.println("Hello, " + name));
Stream API 提供了一种更便捷的方式来处理集合数据,支持函数式编程风格的操作,如过滤、映射、排序等。
List<String> languages = Arrays.asList("Java", "C++", "Python", "JavaScript");
// 使用 Stream 进行过滤和打印
languages.stream()
.filter(lang -> lang.length() > 4)
.forEach(System.out::println);
// 使用 Stream 进行映射和计算
int totalLength = languages.stream()
.mapToInt(String::length)
.sum();
System.out.println("Total length of all languages: " + totalLength);
JDK 8 引入了 java.time
包,提供了新的日期和时间 API,以替代 java.util.Date
和 java.util.Calendar
。
// 获取当前日期和时间
LocalDateTime currentDateTime = LocalDateTime.now();
// 格式化日期时间
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = currentDateTime.format(formatter);
System.out.println("Formatted DateTime: " + formattedDateTime);
在接口中可以定义默认方法和静态方法,这样在不破坏现有实现的情况下可以向接口中添加新的方法。
interface MyInterface {
// 抽象方法
void abstractMethod();
// 默认方法
default void defaultMethod() {
System.out.println("Default Method in MyInterface");
}
// 静态方法
static void staticMethod() {
System.out.println("Static Method in MyInterface");
}
}
class MyClass implements MyInterface {
@Override
public void abstractMethod() {
System.out.println("Implementation of abstractMethod");
}
}
public class Main {
public static void main(String[] args) {
MyClass myClass = new MyClass();
myClass.abstractMethod();
myClass.defaultMethod();
MyInterface.staticMethod();
}
}
JDK 8 引入了 Nashorn,一个新的 JavaScript 引擎,以替代旧的 Rhino 引擎。
// 在Java中调用JavaScript代码
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
try {
engine.eval("print('Hello, Nashorn!');");
} catch (ScriptException e) {
e.printStackTrace();
}
允许在同一位置多次使用相同的注解。
// 重复注解的定义
@Repeatable(MyAnnotations.class)
@interface MyAnnotation {
String value();
}
// 包装重复注解的容器注解
@interface MyAnnotations {
MyAnnotation[] value();
}
// 使用重复注解
@MyAnnotation("first")
@MyAnnotation("second")
public class MyClass {
// class body
}
JDK 8 中移除了永久代(PermGen),取而代之的是元空间(Metaspace),解决了与永久代相关的一些内存管理问题。
CompletableFuture
提供了更强大的异步编程支持,使得异步操作和组合变得更加容易。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")
.thenApplyAsync(s -> s + " World")
.thenAccept(System.out::println);
future.join(); // 等待异步操作完成
方法引用允许通过方法的名字来引用它,使得代码更加简洁。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 使用方法引用
names.forEach(System.out::println);
JDK 8 提供了新的 Base64 编码和解码 API。
import java.util.Base64;
public class Base64Example {
public static void main(String[] args) {
String original = "Hello, Base64!";
// 编码
String encoded = Base64.getEncoder().encodeToString(original.getBytes());
System.out.println("Encoded: " + encoded);
// 解码
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String decoded = new String(decodedBytes);
System.out.println("Decoded: " + decoded);
}
}
JDK 8 引入了一些新的方法和接口,使得集合操作更加便利。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 使用 forEach 迭代集合
names.forEach(System.out::println);
// 使用 removeIf 删除符合条件的元素
names.removeIf(name -> name.startsWith("A"));
System.out.println("After removal: " + names);
JDK 8 引入了一些新的 JVM 选项,用于性能调优和诊断。
// 启用 JVM 的 Flight Recorder
java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder ...
// 启用 JVM 的 Metaspace 大小自动调整
java -XX:+UseG1GC -XX:MaxMetaspaceSize=256m ...
JDK 8 提供了对数组的并行操作,使得数组的处理更加高效。
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 使用 parallelPrefix 对数组进行并行累积
Arrays.parallelPrefix(array, (x, y) -> x * y);
System.out.println("Parallel Prefix: " + Arrays.toString(array));
JDK 8 引入了对类型注解的支持,使得在更多的地方(如泛型、强制类型转换等)可以使用注解。
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
// 类型注解的使用
public class TypeAnnotationExample<@TypeAnnotation T> {
public <@TypeAnnotation U> void myMethod(U u) {
// method body
}
}
try-with-resources
改进在 JDK 7 中引入的 try-with-resources
在 JDK 8 中得到了改进,支持更简洁的语法。
// 在 try-with-resources 中使用多个资源
try (InputStream in = new FileInputStream("input.txt");
OutputStream out = new FileOutputStream("output.txt")) {
// 处理输入输出流
} catch (IOException e) {
e.printStackTrace();
}
Optional
类用于处理可能为 null 的值,JDK 8 对其进行了扩展,提供了更多的方法。
Optional<String> name = Optional.ofNullable(getName());
// 如果值存在,则执行操作
name.ifPresent(n -> System.out.println("Name: " + n));
// 获取值,如果值不存在,则提供默认值
String defaultName = name.orElse("Default");
// 如果值不存在,则抛出异常
String actualName = name.orElseThrow(() -> new RuntimeException("Name not found"));
@FunctionalInterface
注解@FunctionalInterface
注解用于标识一个接口是函数式接口,即只有一个抽象方法的接口。这有助于编译器检查该接口是否符合函数式接口的定义。
@FunctionalInterface
interface MyFunctionalInterface {
void myMethod();
}
// 编译器会检查该接口是否仅包含一个抽象方法
java.util.Optional
扩展Optional
类的扩展,包括 filter
、map
、flatMap
等方法,使得对可选值的处理更加灵活。
Optional<String> name = Optional.ofNullable(getName());
// 使用 map 转换值
Optional<String> upperCaseName = name.map(String::toUpperCase);
// 使用 filter 过滤值
Optional<String> filteredName = name.filter(n -> n.length() > 3);
java.util.function
包引入了新的函数式接口,如 Predicate
、Consumer
、Supplier
和 Function
,使得函数式编程更加方便。
import java.util.function.Predicate;
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 使用 Predicate 过滤集合
List<String> filteredNames = names.stream()
.filter(s -> s.startsWith("A"))
.collect(Collectors.toList());
java.util.stream
包中的其他操作除了之前提到的 Stream API,还有其他的一些操作,如 groupingBy
、partitioningBy
等,用于更复杂的集合操作。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Amy", "Bill");
// 使用 groupingBy 分组
Map<Integer, List<String>> groupedByLength = names.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println("Grouped by length: " + groupedByLength);