首页后端开发JAVAJava20的新特性

Java20的新特性

时间2023-03-27 14:22:25发布访客分类JAVA浏览478
导读:Java语言特性系列Java5的新特性Java6的新特性Java7的新特性Java8的新特性Java9的新特性Java10的新特性Java11的新特性Java12的新特性Java13的新特性Java14的新特性Java15的新特性Java1...

Java语言特性系列

  • Java5的新特性
  • Java6的新特性
  • Java7的新特性
  • Java8的新特性
  • Java9的新特性
  • Java10的新特性
  • Java11的新特性
  • Java12的新特性
  • Java13的新特性
  • Java14的新特性
  • Java15的新特性
  • Java16的新特性
  • Java17的新特性
  • Java18的新特性
  • Java19的新特性
  • Java20的新特性
  • Java21的新特性

本文主要讲述一下Java20的新特性

版本号

java -version
openjdk version "20" 2023-03-21
OpenJDK Runtime Environment (build 20+36-2344)
OpenJDK 64-Bit Server VM (build 20+36-2344, mixed mode, sharing)

从version信息可以看出是build 20+36

特性列表

JEP 429: Scoped Values (Incubator)

ScopedValue是一种类似ThreadLocal的线程内/父子线程传递变量的更优方案。ThreadLocal提供了一种无需在方法参数上传递通用变量的方法,InheritableThreadLocal使得子线程可以拷贝继承父线程的变量。但是ThreadLocal提供了set方法,变量是可变的,另外remove方法很容易被忽略,导致在线程池场景下很容易造成内存泄露。ScopedValue则提供了一种不可变、不拷贝的方案,即不提供set方法,子线程不需要拷贝就可以访问父线程的变量。具体使用如下:

class Server {
    
  public final static ScopedValueUser>
     LOGGED_IN_USER = ScopedValue.newInstance();

 
  private void serve(Request request) {
    
    // ...
    User loggedInUser = authenticateUser(request);
    
    ScopedValue.where(LOGGED_IN_USER, loggedInUser)
               .run(() ->
     restAdapter.processRequest(request));

    // ...
  }

}

通过ScopedValue.where可以绑定ScopedValue的值,然后在run方法里可以使用,方法执行完毕自行释放,可以被垃圾收集器回收

JEP 432: Record Patterns (Second Preview)

JDK19的JEP 405: Record Patterns (Preview)将Record的模式匹配作为第一次preview

JDK20则作为第二次preview

针对嵌套record的推断,可以这样record Point(int x, int y) {
}

enum Color {
 RED, GREEN, BLUE }

record ColoredPoint(Point p, Color c) {
}

record Rectangle(ColoredPoint upperLeft, ColoredPoint lowerRight) {
}


static void printColorOfUpperLeftPoint(Rectangle r) {

    if (r instanceof Rectangle(ColoredPoint(Point p, Color c),
                               ColoredPoint lr)) {
    
        System.out.println(c);

    }

}

整体而言,模式匹配有如下几种:Pattern:
  TypePattern
  ParenthesizedPattern
  RecordPattern

TypePattern:
  LocalVariableDeclaration

ParenthesizedPattern:
  ( Pattern )

RecordPattern:
  ReferenceType RecordStructurePattern

RecordStructurePattern:
  ( [ RecordComponentPatternList ] )

RecordComponentPatternList : 
  Pattern {
 , Pattern }
    
针对泛型推断record BoxT>
(T t) {
}
    

static void test1(BoxString>
 bo) {
    
    if (bo instanceof BoxString>
(var s)) {
    
        System.out.println("String " + s);

    }

}
    也支持嵌套static void test3(BoxBoxString>
    >
 bo) {
    
    if (bo instanceof BoxBoxString>
    >
(Box(var s))) {
        
        System.out.println("String " + s);

    }

}

JEP 433: Pattern Matching for switch (Fourth Preview)

在JDK14JEP 305: Pattern Matching for instanceof (Preview)作为preview

在JDK15JEP 375: Pattern Matching for instanceof (Second Preview)作为第二轮的preview

在JDK16JEP 394: Pattern Matching for instanceof转正

JDK17引入JEP 406: Pattern Matching for switch (Preview)

JDK18的JEP 420: Pattern Matching for switch (Second Preview)则作为第二轮preview

JDK19的JEP 427: Pattern Matching for switch (Third Preview)作为第三轮preview

JDK20作为第四轮preview

自第三次预览以来的主要变化是:

  • 针对枚举类型出现无法匹配的时候抛出MatchException而不是IncompatibleClassChangeError
  • 开关标签的语法更简单
  • switch现在支持record泛型的推断

以前针对null值switch会抛出异常,需要特殊处理

static void testFooBar(String s) {

    if (s == null) {
    
        System.out.println("Oops!");
    
        return;

    }

    switch (s) {
    
        case "Foo", "Bar" ->
     System.out.println("Great");
    
        default           ->
     System.out.println("Ok");

    }

}

现在可以直接switch

static void testFooBar(String s) {

    switch (s) {
    
        case null         ->
     System.out.println("Oops");
    
        case "Foo", "Bar" ->
     System.out.println("Great");
    
        default           ->
     System.out.println("Ok");

    }

}

case when的支持,以前这么写

class Shape {
}

class Rectangle extends Shape {
}

class Triangle  extends Shape {
 int calculateArea() {
 ... }
 }


static void testTriangle(Shape s) {

    switch (s) {
    
        case null:
            break;
    
        case Triangle t:
            if (t.calculateArea() >
 100) {
    
                System.out.println("Large triangle");
    
                break;

            }
    
        default:
            System.out.println("A shape, possibly a small triangle");

    }

}

现在可以这么写

static void testTriangle(Shape s) {

    switch (s) {
    
        case null ->
 
            {
     break;
 }
    
        case Triangle t
        when t.calculateArea() >
     100 ->
    
            System.out.println("Large triangle");
    
        case Triangle t ->
    
            System.out.println("Small triangle");
    
        default ->
    
            System.out.println("Non-triangle");

    }

}
    

针对record泛型的类型推断:

record MyPairS,T>
(S fst, T snd){
}
    ;
    

static void recordInference(MyPairString, Integer>
 pair){

    switch (pair) {
    
        case MyPair(var f, var s) ->
     
            ... // Inferred record Pattern MyPairString,Integer>
(var f, var s)
        ...
    }

}
    

JEP 434: Foreign Function & Memory API (Second Preview)

Foreign Function & Memory (FFM) API包含了两个incubating API

JDK14的JEP 370: Foreign-Memory Access API (Incubator)引入了Foreign-Memory Access API作为incubator

JDK15的JEP 383: Foreign-Memory Access API (Second Incubator)Foreign-Memory Access API作为第二轮incubator

JDK16的JEP 393: Foreign-Memory Access API (Third Incubator)作为第三轮,它引入了Foreign Linker API (JEP 389)

FFM API在JDK 17的JEP 412: Foreign Function & Memory API (Incubator)作为incubator引入

FFM API在JDK 18的JEP 419: Foreign Function & Memory API (Second Incubator)作为第二轮incubator

JDK19的JEP 424: Foreign Function & Memory API (Preview)则将FFM API作为preview API

JDK20作为第二轮preview

使用示例

 javac --release 20 --enable-preview ... and java --enable-preview ....

// 1. Find foreign function on the C library path
Linker linker          = Linker.nativeLinker();
    
SymbolLookup stdlib    = linker.defaultLookup();
    
MethodHandle radixsort = linker.downcallHandle(stdlib.find("radixsort"), ...);

// 2. Allocate on-heap memory to store four strings
String[] javaStrings = {
 "mouse", "cat", "dog", "car" }
    ;

// 3. Use try-with-resources to manage the lifetime of off-heap memory
try (Arena offHeap = Arena.openConfined()) {
    
    // 4. Allocate a region of off-heap memory to store four pointers
    MemorySegment pointers = offHeap.allocateArray(ValueLayout.ADDRESS, javaStrings.length);
    
    // 5. Copy the strings from on-heap to off-heap
    for (int i = 0;
     i  javaStrings.length;
 i++) {
    
        MemorySegment cString = offHeap.allocateUtf8String(javaStrings[i]);
    
        pointers.setAtIndex(ValueLayout.ADDRESS, i, cString);

    }
    
    // 6. Sort the off-heap data by calling the foreign function
    radixsort.invoke(pointers, javaStrings.length, MemorySegment.NULL, '\0');
    
    // 7. Copy the (reordered) strings from off-heap to on-heap
    for (int i = 0;
     i  javaStrings.length;
 i++) {
    
        MemorySegment cString = pointers.getAtIndex(ValueLayout.ADDRESS, i);
    
        javaStrings[i] = cString.getUtf8String(0);

    }

}
 // 8. All off-heap memory is deallocated here
assert Arrays.equals(javaStrings, new String[] {
"car", "cat", "dog", "mouse"}
    );
  // true

JEP 436: Virtual Threads (Second Preview)

在JDK19https://openjdk.org/jeps/425作为第一次preview

在JDK20作为第二次preview,此版本java.lang.ThreadGroup被永久废弃

使用示例

void handle(Request request, Response response) {

    var url1 = ...
    var url2 = ...
 
    try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    
        var future1 = executor.submit(() ->
     fetchURL(url1));
    
        var future2 = executor.submit(() ->
     fetchURL(url2));
    
        response.send(future1.get() + future2.get());

    }
 catch (ExecutionException | InterruptedException e) {
    
        response.fail(e);

    }

}

 
String fetchURL(URL url) throws IOException {

    try (var in = url.openStream()) {
    
        return new String(in.readAllBytes(), StandardCharsets.UTF_8);

    }

}
    

JEP 437: Structured Concurrency (Second Incubator)

在JDK19JEP 428: Structured Concurrency (Incubator)作为第一次incubator

在JDK20作为第二次incubator

JEP 438: Vector API (Fifth Incubator)

JDK16引入了JEP 338: Vector API (Incubator)提供了jdk.incubator.vector来用于矢量计算

JDK17进行改进并作为第二轮的incubatorJEP 414: Vector API (Second Incubator)

JDK18的JEP 417: Vector API (Third Incubator)进行改进并作为第三轮的incubator

JDK19JEP 426:Vector API (Fourth Incubator)作为第四轮的incubator

JDK20作为第五轮的incubator

细项解读

上面列出的是大方面的特性,除此之外还有一些api的更新及废弃,主要见JDK 20 Release Notes,这里举几个例子。

添加项

  • Support Unicode 15.0 Update Unicode Data Files to 15.0.0
  • Add GarbageCollectorMXBean for Remark and Cleanup Pause Time in G1 JDK-8297247

移除项

  • Thread.suspend/resume Changed to Throw UnsupportedOperationException JDK-8249627-XX:-G1UseAdaptiveConcRefinement -XX:G1ConcRefinementGreenZone=buffer-count -XX:G1ConcRefinementYellowZone=buffer-count -XX:G1ConcRefinementRedZone=buffer-count -XX:G1ConcRefinementThresholdStep=buffer-count -XX:G1ConcRefinementServiceIntervalMillis=msec
  • Thread.Stop Changed to Throw UnsupportedOperationException JDK-8289610
  • Improved Control of G1 Concurrent Refinement Threads JDK-8137022以下这些参数未来版本移除

废弃项

完整列表见Java SE 20 deprecated-list

  • java.net.URL Constructors Are Deprecated JDK-8294241URL的构造器被废弃,可以使用URL::of(URI, URLStreamHandler)工厂方法替代

已知问题

  • java.lang.Float.floatToFloat16 and java.lang.Float.float16ToFloat May Return Different NaN Results when Optimized by the JIT Compiler (JDK-8302976, JDK-8289551, JDK-8289552)JDK20引入了java.lang.Float.floatToFloat16及java.lang.Float.float16ToFloat方法,在JIT编译优化时可能会返回不同的Nan结果,可以使用如下参数禁用JIT对此的优化-XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_floatToFloat16,_float16ToFloat

其他事项

  • Disabled TLSECDH* Cipher Suites (JDK-8279164)TLSECDH* cipher suites默认被禁用了
  • HTTP Response Input Streams Will Throw an IOException on Interrupt (JDK-8294047)
  • HttpClient Default Keep Alive Time is 30 Seconds (JDK-8297030)http1.1及http2的空闲连接的超时时间从1200秒改为30秒

小结

Java20主要有如下几个特性

  • JEP 429: Scoped Values (Incubator)
  • JEP 432: Record Patterns (Second Preview)
  • JEP 433: Pattern Matching for switch (Fourth Preview)
  • JEP 434: Foreign Function & Memory API (Second Preview)
  • JEP 436: Virtual Threads (Second Preview)
  • JEP 437: Structured Concurrency (Second Incubator)
  • JEP 438: Vector API (Fifth Incubator)

doc

  • JDK 20 Features
  • JDK 20 Release Notes
  • Consolidated JDK 20 Release Notes
  • Java SE 20 deprecated-list
  • The Arrival of Java 20
  • JDK 20 G1/Parallel/Serial GC changes
  • Java 20 Delivers Features for Projects Amber, Loom and Panama
  • Java 20: a faster future is Looming
  • JDK 20 Security Enhancements
  • Project Loom’s Scoped Values: The Most Interesting New Java 20 Feature

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: Java20的新特性
本文地址: https://pptw.com/jishu/373.html
漫谈模式之行为模式小结(行为模式的概念) 学习研究Jrebel自建激活服务器 – 支持全部版本IDEA

游客 回复需填写必要信息