Osmanthus

空想具現化


  • 首页
  • 归档
  • 分类
  • 标签
  • 关于
  •   

© 2024 Homurax

UV: | PV:

Theme Typography by Makito

Proudly published with Hexo

Java 21 新特性(18 ~ 21)

发布于 2024-05-13 Java  Feature 

Java 18

JEP 408:简单 Web 服务器

JEP 408: Simple Web Server
https://openjdk.org/jeps/408

The jwebserver Command
https://docs.oracle.com/en/java/javase/21/docs/specs/man/jwebserver.html

可以使用 jwebserver 命令启动一个简易的静态 Web 服务器。

从目标来说,提供了一个命令行工具来启动仅提供静态文件的最小 Web 服务器。
主要用于原型设计、临时编码和测试目的场景,具有简单的设置和最少的功能。

public static void main(String[] args) {  
    InetSocketAddress addr = new InetSocketAddress(8000);  
    HttpServer server = SimpleFileServer.createFileServer(  
            addr, Path.of(System.getProperty("user.dir")), SimpleFileServer.OutputLevel.INFO);  
    server.start();  
}

等价于

jwebserver -p 8000 -d / -b 127.0.0.1 -o info
  • -b:绑定地址
  • -d:供服务的目录
  • -o:输出级别
  • -p:端口

JEP 413:Java API 文档中的代码片段

JEP 413: Code Snippets in Java API Documentation
https://openjdk.org/jeps/413

新增 @snipppet 标签。

在 Java 18 之前,如果要在 Javadoc 中引入代码片段,需要使用 <pre>{@code ...}</pre>,使用上等同于文本编辑器。

/**  
 * The following code shows how to use {@code Optional.isPresent}:  
 * <pre>{@code  
 *  if (v.isPresent()) {  
 *      System.out.println("v: " + v.get()); *  } * }
 * </pre>  
 */

使用 @snipppet,在 IDE 中可以获得高亮与代码提示支持。

/**  
 * The following code shows how to use {@code Optional.isPresent}:  
 * {@snippet :  
 * if (v.isPresent()) {  
 *    System.out.println("v: " + v.get());  
 * }  
 * }
 */

Java 21

常规方法增加

表请符号支持

Java 21中 在 Character 类中增加了用于确定字符是否为 Emoji 的方法。

https://bugs.openjdk.org/browse/JDK-8303018
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Character.html
https://unicode.org/reports/tr51/#Emoji_Properties_and_Data_Files

// 是否为 Emoji
public static boolean isEmoji(int codePoint)
// 是否为 Emoji 组件(具有标准中的定义的 Emoji_Component 属性)
public static boolean isEmojiComponent(int codePoint)
// Emoji 是否被修改(Emoji_Modifier 属性)
public static boolean isEmojiModifier(int codePoint)
// Emoji 是否可修改(Emoji_Modifier_Base 属性)
public static boolean isEmojiModifierBase(int codePoint)
// 确定指定字符默认情况下是否具有表情符号表示属性(Emoji_Presentation 属性)
public static boolean isEmojiPresentation(int codePoint)
// 确定指定字符是否是扩展象形文字(Extended_Pictographic 属性)
public static boolean isExtendedPictographic(int codePoint)
String msg1 = "Hey Java Developers! ☕️";  
if (msg1.codePoints().anyMatch(Character::isEmoji)) {  
    System.out.println("Message contains an emoji");  
}  

String msg2 = "Hey Java Developers! 🙋🏻‍♂️";  
OptionalInt emojiOptional = msg2.codePoints().filter(Character::isEmoji).findFirst();  
if (emojiOptional.isPresent()) {  
    int emojiCodePoint = emojiOptional.getAsInt();  
    if (Character.isEmojiModifierBase(emojiCodePoint)) {  
        System.out.println("Emoji can be modified");  
        if (Character.isEmojiModifier(emojiCodePoint)) {  
            System.out.println("Emoji is modified");  
        } else {  
            System.out.println("Emoji has not been modified");  
        }  
    } else {  
        System.out.println("Emoji cannot be modified");  
    }  
} else {  
    System.out.println("No emoji");  
}

对 Emoji 的正则支持。

String msg1 = "Hey Java Developers! ☕️";  
Matcher matcher1 = Pattern.compile("\\p{IsEmoji}").matcher(msg1);  
if (matcher1.find()) {  
    System.out.println("Message contains an emoji!");  
}

String msg2 = "Hey Java Developers! 🙋🏻‍♂️";  
Matcher matcher2 = Pattern.compile("\\p{IsEmoji_Modifier_Base}").matcher(msg2);  
if (matcher2.find()) {  
    System.out.println("Message contains an emoji modifier base!");  
}

StringBuilder、StringBuffer 新增 repeat 方法

https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/StringBuilder.html#repeat(int,int)
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/StringBuffer.html#repeat(int,int)

StringBuilder sb = new StringBuilder();  
// CharSequence、int
sb.repeat('a', 5).repeat("str", 5);  
System.out.println(sb);

JEP 431:有序集合

JEP 431: Sequenced Collections
https://openjdk.org/jeps/431

增加了三个新接口:

  • SequencedCollection
  • SequencedMap
  • SequencedSet

在 JDK 21 之前,获取有序集合中第一个元素和最后一个元素的 api 并不统一,取决于具体类型。

First element Last element
List list.get(0) list.get(list.size() - 1)
Deque deque.getFirst() deque.getLast()
SortedSet sortedSet.first() sortedSet.last()
LinkedHashSet linkedHashSet.iterator().next() // missing

通过本次新增的三个接口,可以将相关调用进行统一。

JEP 440:Record 模式

JEP 440: Record Patterns
https://openjdk.org/jeps/440

现在可以对复杂嵌套的 Record 类解构,配合 instanceof 或 switch 使用。

interface Geometry { }  
record Point(int x, int y) implements Geometry { }  
record Size(int length, int width) implements Geometry { }  
record Rectangle(Point point, Size size) implements Geometry { }  

Point point = new Point(3, 7);  
Size size = new Size(10, 5);  
Object rectangle = new Rectangle(point, size);  

if (rectangle instanceof Rectangle(Point p, Size(int l, int w))) {  
    System.out.println("(" + p.x + ", " + p.y + ")");  
    System.out.println("area = " + l * w);  
}  

switch (rectangle) {  
    case Point p -> System.out.println(p);  
    case Size s -> System.out.println(s);  
    case Rectangle(Point p, Size(int l, int w)) -> System.out.println("area = " + l * w);  
    default -> System.out.println("Unknown");  
}

JEP 441:switch 模式匹配

JEP 441: Pattern Matching for switch
https://openjdk.org/jeps/441

对于不确定类型的对象判断时,可以用 switch 代替 instanceof。

for (Object obj : new Object[]{null, 1, 1L, 1.0, "str"}) {  
    String rst = switch (obj) {  
        // 可以判断 null        
        case null -> "null";  
        case Integer i -> String.format("int %d", i);  
        case Long l -> String.format("long %d", l);  
        case Double d -> String.format("double %f", d);  
        case String s -> String.format("string %s", s);  
        default -> obj.toString();  
    };  
    System.out.println(rst);  
}

JEP 444:虚拟线程

https://blog.homurax.com/2024/05/13/virtual-threads/

 上一篇: Peewee:简单、轻量化的 ORM 下一篇: Java 21 虚拟线程(Virtual Threads) 

© 2024 Homurax

UV: | PV:

Theme Typography by Makito

Proudly published with Hexo