Java 13于2019年9月17日正式发布供生产使用。由于采用了6个月的发布周期,Java 13中没有太多面向开发者的特性。
Java 13特性
一些重要的Java 13特性包括:
- 文本块 – JEP 355
- 文本块中String类的新方法
- Switch表达式增强 – JEP 354
- 重新实现Legacy Socket API – JEP 353
- 动态CDS存档 – JEP 350
- ZGC:释放未使用的内存 – JEP 351
- FileSystems.newFileSystem()方法
- 支持Unicode 12.1
- 具有命名空间支持的DOM和SAX工厂
如何启用预览特性
Switch表达式和文本块是预览特性。因此,您需要在项目中启用预览特性设置。如果您从命令行运行Java程序,可以使用--enable-preview
开关启用它。您可以使用此开关启动具有启用预览特性的JShell。
$ jshell --enable-preview
$ java --enable-preview --source 13 Test.java
如果您使用Eclipse IDE,可以在项目的Java编译器设置中启用预览特性。

1. 文本块 – JEP 355
这是一个预览功能。它允许我们轻松创建多行字符串。多行字符串必须写在一对三重双引号之间。使用文本块创建的字符串对象没有额外的属性。这是创建多行字符串的一种更简单的方式。我们不能使用文本块创建单行字符串。开头的三重双引号后必须跟随一个换行符。
package com.journaldev.java13.examples;
public class TextBlockString {
/**
* JEP 355: Preview Feature
*/
@SuppressWarnings("preview")
public static void main(String[] args) {
String textBlock = """
Hi
Hello
Yes""";
String str = "Hi\nHello\nYes";
System.out.println("Text Block String:\n" + textBlock);
System.out.println("Normal String Literal:\n" + str);
System.out.println("Text Block and String Literal equals() Comparison: " + (textBlock.equals(str)));
System.out.println("Text Block and String Literal == Comparison: " + (textBlock == str));
}
}
输出:
Text Block String:
Hi
Hello
Yes
Normal String Literal:
Hi
Hello
Yes
Text Block and String Literal equals() Comparison: true
Text Block and String Literal == Comparison: true
在我们的Java程序中,它在轻松创建HTML和JSON字符串方面非常有用。
String textBlockHTML = """
<html>
<head>
<link href='/css/style.css' rel='stylesheet' />
</head>
<body>
<h1>Hello World</h1>
</body>
</html>""";
String textBlockJSON = """
{
"name":"Pankaj",
"website":"JournalDev"
}""";
2. 字符串类中的新方法用于文本块
字符串类中有三个与文本块功能相关的新方法。
- formatted(Object… args): 它类似于String的format()方法。它被添加以支持在文本块中进行格式化。
- stripIndent(): 用于从文本块中的每一行的开头和结尾删除不必要的空白字符。此方法被文本块使用,并保留内容的相对缩进。
- translateEscapes(): 返回一个字符串,其值为此字符串,其中转义序列被转换,就像在字符串文字中一样。
package com.journaldev.java13.examples;
public class StringNewMethods {
/***
* New methods are to be used with Text Block Strings
* @param args
*/
@SuppressWarnings("preview")
public static void main(String[] args) {
String output = """
Name: %s
Phone: %d
Salary: $%.2f
""".formatted("Pankaj", 123456789, 2000.5555);
System.out.println(output);
String htmlTextBlock = "<html> \n"+
"\t<body>\t\t \n"+
"\t\t<p>Hello</p> \t \n"+
"\t</body> \n"+
"</html>";
System.out.println(htmlTextBlock.replace(" ", "*"));
System.out.println(htmlTextBlock.stripIndent().replace(" ", "*"));
String str1 = "Hi\t\nHello' \" /u0022 Pankaj\r";
System.out.println(str1);
System.out.println(str1.translateEscapes());
}
}
输出:
Name: Pankaj
Phone: 123456789
Salary: $2000.56
<html>***
<body> *
<p>Hello</p>** *
</body>*
</html>
<html>
<body>
<p>Hello</p>
</body>
</html>
Hi
Hello' " /u0022 Pankaj
Hi
Hello' " /u0022 Pankaj
3. Switch 表达式增强 – JEP 354
Switch 表达式在 Java 12 版本中作为预览功能添加。在 Java 13 中,除了将 “break” 替换为 “yield” 以从 case 语句返回值外,几乎相同。
package com.journaldev.java13.examples;
/**
* JEP 354: Switch Expressions
* https://openjdk.java.net/jeps/354
* @author pankaj
*
*/
public class SwitchEnhancements {
@SuppressWarnings("preview")
public static void main(String[] args) {
int choice = 2;
switch (choice) {
case 1:
System.out.println(choice);
break;
case 2:
System.out.println(choice);
break;
case 3:
System.out.println(choice);
break;
default:
System.out.println("integer is greater than 3");
}
// 从 Java 13 开始 - 多标签 case 语句
switch (choice) {
case 1, 2, 3:
System.out.println(choice);
break;
default:
System.out.println("integer is greater than 3");
}
// switch 表达式,使用 yield 返回,在 Java 12 中是 break
int x = switch (choice) {
case 1, 2, 3:
yield choice;
default:
yield -1;
};
System.out.println("x = " + x);
}
enum Day {
SUN, MON, TUE
};
@SuppressWarnings("preview")
public String getDay(Day d) {
String day = switch (d) {
case SUN -> "Sunday";
case MON -> "Monday";
case TUE -> "Tuesday";
};
return day;
}
}
4. 重新实现传统套接字 API – JEP 353
java.net.Socket 和 java.net.ServerSocket API 的底层实现已被重写。新的实现,NioSocketImpl,是 PlainSocketImpl 的可插拔替代品。它使用 java.util.concurrent 锁而不是同步方法。如果要使用传统实现,请使用 Java 选项 -Djdk.net.usePlainSocketImpl。
5. 动态CDS存档 – JEP 350
这个JEP扩展了在Java 10中引入的类数据共享功能。现在,创建CDS存档并使用它变得更容易了。
$ java -XX:ArchiveClassesAtExit=my_app_cds.jsa -cp my_app.jar
$ java -XX:SharedArchiveFile=my_app_cds.jsa -cp my_app.jar
6. ZGC:释放未使用的内存 – JEP 351
这个JEP增强了ZGC,将未使用的堆内存归还给操作系统。Z垃圾收集器是在Java 11中引入的。它在清理堆内存之前增加了短暂的暂停时间。但是,未使用的内存并没有被归还给操作系统。这对于内存占用较小的设备,如物联网和微控制器,是一个问题。现在,它已经改进,可以将未使用的内存归还给操作系统。
7. FileSystems.newFileSystem() 方法
FileSystems类新增了三种新方法,以便更轻松地使用文件系统提供程序,这些方法将文件的内容视为文件系统。
- newFileSystem(Path)
- newFileSystem(Path,Map<String,?>)
- newFileSystem(Path,Map<String,?>,ClassLoader)
8. 带命名空间支持的DOM和SAX工厂
现在有了实例化带命名空间支持的DOM和SAX工厂的新方法。
- newDefaultNSInstance()
- newNSInstance()
- newNSInstance(String factoryClassName,ClassLoader classLoader)
//java 13及更高版本
DocumentBuilder db = DocumentBuilderFactory.newDefaultNSInstance().newDocumentBuilder();
// 在java 13之前
DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
结论
看起来,Java每6个月的发布效果很好。没有太多针对开发人员的特定功能,但总体而言这是一个很棒的发布。很高兴看到期待已久的文本块字符串支持。
参考资料
- <文本块示例>
Source:
https://www.digitalocean.com/community/tutorials/java-13-features