主要特性
版本 | 特性 |
---|---|
Java 10 | 1. var 声明局部变量 |
Java 11 (LTS) | 1. 字符串补充工具方法 2. lambda 类型推断 |
Java 12 | 1. switch 箭头表达式 |
Java 13 | 1. switch 支持返回值,增加yield关键字 2. 多行字符串 |
Java 14 | 1. instanceof优化 2. NPE优化 3. record类型 |
Java 15 | 1. scale密封类 |
Java 16 | 1. 包装类构造方法警告 2. DateTimeFormatter增加匹配方式 3. InvocationHandler新增方法 |
Java 10
var
声明局部变量
/**
* @author imyzt
* @date 2023/12/16
* @description Var
*/
public class VarDemo {
public static void main(String[] args) {
var str = "hello world";
var num = 10;
System.out.println(str);
System.out.println(num);
}
}
Java 11
字符串补充工具方法, lambda 类型推断
/**
* @author imyzt
* @date 2023/12/16
* @description String 补充工具方法
*/
public class StrUtil {
public static void main(String[] args) {
//Unicode空白字符
char c = '\u2000';
String str = c + "abc" + c;
// 去除普通空白字符
System.out.println(str.trim());
// 去除Unicode空白字符
System.out.println(str.strip());
// 去除前面的空白字符
System.out.println(str.stripLeading());
// 去除后面的空白字符
System.out.println(str.stripTrailing());
// abc
//abc
//abc
// abc
// 判空
System.out.println(" ".isBlank());
// 支持直接定义常量使用format
System.out.println("%s_%s".formatted("a", "b"));
// 重复字符串
System.out.println("abc".repeat(3));
//true
//a_b
//abcabcabc
// lambda 类型推断
// java11前
MyFunc s1 = (String a, Integer b) -> a + b;
MyFunc s2 = (a, b) -> a + b;
// java11后, 支持类型推断(作用不大)
MyFunc s3 = (var a, var b) -> a + b;
}
}
@FunctionalInterface
interface MyFunc {
String foo(String a, Integer b);
}
Java 12
switch 箭头表达式
/**
* @author imyzt
* @date 2023/12/16
* @description switch
*/
public class SwitchFuture {
public static void main(String[] args) {
int month = LocalDate.now().getMonthValue();
// java12 前 switch
switch (month) {
case 3:
case 4:
case 5:
System.out.println("spring");
break;
case 6:
case 7:
case 8:
System.out.println("summer");
break;
case 9:
case 10:
case 11:
System.out.println("fall");
break;
case 12:
case 1:
case 2:
System.out.println("winter");
break;
default:
System.out.println("err");
}
// java12 之后的switch
switch (month) {
case 3,4,5 -> System.out.println("spring");
case 6,7,8 -> System.out.println("summer");
case 9,10,11 -> System.out.println("fall");
case 12,1,2 -> System.out.println("winter");
default -> System.out.println("err");
}
}
}
Java 13
switch 箭头表达式支持返回值,多行字符串,增加yield关键字作为switch多行时的返回值
import java.time.LocalDate;
/**
* @author imyzt
* @date 2023/12/16
* @description switch 返回值
*/
public class SwitchFuture {
public static void main(String[] args) {
int month = LocalDate.now().getMonthValue();
// java13 之后的switch
String str = switch (month) {
case 3, 4, 5 -> "spring";
case 6, 7, 8 -> "summer";
case 9, 10, 11 -> "fall";
case 12, 1, 2 -> "winter";
default -> {
System.out.println("err");
yield "err";
}
};
System.out.println(str);
// winter
String strline = """
第一行
第二行
第三行""";
System.out.println(strline);
//第一行
//第二行
//第三行
}
}
Java 14
instanceof 优化
/**
* @author imyzt
* @date 2023/12/16
* @description instanceof 优化
*/
public class InstanceofFuture {
public static void main(String[] args) {
// Java 14之前
Object o = "str";
if (o instanceof String) {
String str = (String) o;
System.out.println(str);
}
// Java 14之后
if (o instanceof String str) {
System.out.println(str);
}
}
}
NPE优化,在链式调用时, 如果有空指针, 可以明确是哪个变量空指针
/**
* @author imyzt
* @date 2023/12/16
* @description 友好的NPE提示
*/
public class NpeFuture {
public static void main(String[] args) {
C c = new C();
// 在链式调用时, 如果有空指针, 可以明确是哪个变量空指针
String name = c.b.a.name;
System.out.println(name);
// Cannot read field "a" because "c.b" is null
}
}
class A {
public String name;
}
class B {
public A a;
}
class C {
public B b;
}
record模式
/**
* @author imyzt
* @date 2023/12/16
* @description record模式
*/
public class RecordFuture {
public static void main(String[] args) {
Student student = new Student("yzt", 25);
System.out.println(student);
// Student[name=yzt, age=25]
student.study();
// good good study!
}
}
record Student(String name, Integer age) {
public void study() {
System.out.println("good good study!");
}
}
Java 15
scale密封类
- 需要使用
sealed
声明, 使用permits
指定 - 继承密封类,必须指定自己为final(Dog),或选择继续将自己指定为密封类(Cat)
/**
* @author imyzt
* @date 2023/12/16
* @description scale, permits
*/
public class ScaleFuture {
}
/**
* 只希望Dog和Cat能继承, 需要使用sealed声明, 使用permits指定
*/
sealed class Animal permits Dog, Cat {
}
/**
* 继承密封类,必须指定自己为final(Dog), 或继续将自己指定为密封类(Cat)
*/
final class Dog extends Animal {
}
/**
* 将自己指定为密封类, 并且通过permits指定只有Cat2能够继承
*/
sealed class Cat extends Animal permits Cat2 {
}
final class Cat2 extends Cat {
}
Java 16
包装类型的构造方法被标记过期
/**
* @author imyzt
* @date 2023/12/17
* @description Integer
*/
public class IntegerFuture {
public static void main(String[] args) {
// 'Integer(int)' is deprecated and marked for removal
Integer i = new Integer(2);
System.out.println(i);
// 不建议这样编写,因为数字在常量池中, 会和其他毫不相干的地方使用同一个锁对象
synchronized (i) {
System.out.println(1);
}
// time format
// All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters. The following pattern letters are defined:
System.out.println(DateTimeFormatter.ofPattern("B").format(LocalDateTime.now()));
//2
//1
//凌晨
}
}
DateTimeFormatter
Symbol | Meaning | Presentation | Examples |
---|---|---|---|
G | era | text | AD; Anno Domini; A |
u | year | year | 2004; 04 |
y | year-of-era | year | 2004; 04 |
D | day-of-year | number | 189 |
M/L | month-of-year | number/text | 7; 07; Jul; July; J |
d | day-of-month | number | 10 |
g | modified-julian-day | number | 2451334 |
Q/q | quarter-of-year | number/text | 3; 03; Q3; 3rd quarter |
Y | week-based-year | year | 1996; 96 |
w | week-of-week-based-year | number | 27 |
W | week-of-month | number | 4 |
E | day-of-week | text | Tue; Tuesday; T |
e/c | localized day-of-week | number/text | 2; 02; Tue; Tuesday; T |
F | day-of-week-in-month | number | 3 |
a | am-pm-of-day | text | PM |
B | period-of-day | text | in the morning |
h | clock-hour-of-am-pm (1-12) | number | 12 |
K | hour-of-am-pm (0-11) | number | 0 |
k | clock-hour-of-day (1-24) | number | 24 |
H | hour-of-day (0-23) | number | 0 |
m | minute-of-hour | number | 30 |
s | second-of-minute | number | 55 |
S | fraction-of-second | fraction | 978 |
A | milli-of-day | number | 1234 |
n | nano-of-second | number | 987654321 |
N | nano-of-day | number | 1234000000 |
V | time-zone ID | zone-id | America/Los_Angeles; Z; -08:30 |
v | generic time-zone name | zone-name | Pacific Time; PT |
z | time-zone name | zone-name | Pacific Standard Time; PST |
O | localized zone-offset | offset-O | GMT+8; GMT+08:00; UTC-08:00 |
X | zone-offset 'Z' for zero | offset-X | Z; -08; -0830; -08:30; -083015; -08:30:15 |
x | zone-offset | offset-x | +0000; -08; -0830; -08:30; -083015; -08:30:15 |
Z | zone-offset | offset-Z | +0000; -0800; -08:00 |
p | pad next | pad modifier | 1 |
' | escape for text | delimiter | |
'' | single quote | literal | ' |
[ | optional section start | ||
] | optional section end | ||
# | reserved for future use | ||
{ | reserved for future use | ||
} | reserved for future use |
InvocationHandler新增方法
该接口补充了新方法 java.lang.reflect.InvocationHandler#invokeDefault
,可以调用父接口中的default
方法。
@CallerSensitive
public static Object invokeDefault(Object proxy, Method method, Object... args)
throws Throwable {
Objects.requireNonNull(proxy);
Objects.requireNonNull(method);
return Proxy.invokeDefault(proxy, method, args, Reflection.getCallerClass());
}