Java 11 到 Java 8 的兼容性转换
欲倚绿窗伴卿卿,颇悔今生误道行。有心持钵丛林去,又负美人一片情。
静坐修观法眼开,祈求三宝降灵台,观中诸圣何曾见?不请情人却自来。
入山投谒得道僧,求教上师说因明。争奈相思无拘检,意马心猿到卿卿。
曾虑多情损梵行,入山又恐别倾城,世间安得两全法,不负如来不负卿
随着Java版本的更新,新的特性和改进不断被引入以提升开发效率和性能。然而,对于仍在使用Java 8的项目,需要将使用Java 11特性的代码转换为兼容Java 8的形式。难搞啊,世间安有两全法!
1. 使用InputStream
和文件I/O
Java 11引入了便利的方法如InputStream.readAllBytes()
和Files.writeString()
来简化文件操作。但在Java 8中,这些方法并不存在,因此需要使用替代方案。
原Java 11代码:
public boolean createOrUpdateFile(final Path path, final ByteArrayInputStream stream) {
if (!Files.exists(path)) {
return createFile(path, stream);
} else {
try {
Files.write(path, stream.readAllBytes());
return true;
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
转换为Java 8的代码:
public boolean createOrUpdateFile(final Path path, final ByteArrayInputStream stream) {
if (!Files.exists(path)) {
return createFile(path, stream);
} else {
try {
byte[] buffer = new byte[stream.available()];
stream.read(buffer);
Files.write(path, buffer);
return true;
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
2. URL连接和异常处理
在Java 11中,可以直接使用InputStream.readAllBytes()
从InputStream
读取所有字节。Java 8中需要手动处理。
原Java 11代码:
if (url == null || url.isEmpty()) {
throw new RuntimeException("Url argument is not specified");
}
URL uri = new URL(url);
HttpURLConnection connection = (HttpURLConnection) uri.openConnection();
connection.setConnectTimeout(FILE_SAVE_TIMEOUT);
InputStream stream = connection.getInputStream();
int statusCode = connection.getResponseCode();
if (statusCode != HttpStatus.OK.value()) {
connection.disconnect();
throw new RuntimeException("Document editing service returned status: " + statusCode);
}
if (stream == null) {
connection.disconnect();
throw new RuntimeException("Input stream is null");
}
return stream.readAllBytes();
转换为Java 8的代码:
if (url == null || url.isEmpty()) {
throw new RuntimeException("Url argument is not specified");
}
URL uri = new URL(url);
HttpURLConnection connection = (HttpURLConnection) uri.openConnection();
connection.setConnectTimeout(FILE_SAVE_TIMEOUT);
InputStream stream = connection.getInputStream();
int statusCode = connection.getResponseCode();
if (statusCode != HttpStatus.OK.value()) {
connection.disconnect();
throw new RuntimeException("Document editing service returned status: " + statusCode);
}
if (stream == null) {
connection.disconnect();
throw new RuntimeException("Input stream is null");
}
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[1024];
while ((nRead = stream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
return buffer.toByteArray();
3. 使用List.of()
Java 9引入了List.of()
等集合工厂方法。在Java 8中,可以使用Arrays.asList()
或者手动创建并添加元素。
原Java 11代码:
public List<Template> createTemplates(final String fileName) {
List<Template> templates = List.of(
new Template("", "Blank", documentManager.getCreateUrl(fileName, false)),
new Template(getTemplateImageUrl(fileName), "With sample content", documentManager.getCreateUrl(fileName, true))
);
return templates;
}
转换为Java 8的代码:
public List<Template> createTemplates(final String fileName) {
List<Template> templates = new ArrayList<>();
templates.add(new Template("", "Blank", documentManager.getCreateUrl(fileName, false)));
templates.add(new Template(getTemplateImageUrl(fileName), "With sample content", documentManager.getCreateUrl(fileName, true)));
return templates;
}
4. var
关键字
Java 11引入了局部变量类型推断(Local-Variable Type Inference),即 var
关键字。Java 8中没有这个特性,因此需要将所有使用 var
的地方替换为明确的类型声明。
Java 11 示例:
var list = new ArrayList<String>();
var stream = Files.newInputStream(path);
转换为Java 8:
ArrayList<String> list = new ArrayList<>();
InputStream stream = Files.newInputStream(path);
5. 新的字符串方法
Java 11为String
类引入了多个新方法,如isBlank()
, lines()
, strip()
, repeat()
等。这些在Java 8中都不可用,需要手动实现或用其他方式替换。
Java 11 示例:
var result = " Test ".strip(); // 移除首尾空格
var count = "Hello".repeat(3); // 重复字符串
转换为Java 8:
String result = " Test ".trim(); // 使用trim()方法移除首尾空白
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 3; i++) sb.append("Hello");
String count = sb.toString();
6. 文件操作的新方法
Java 11增强了Files
和Path
类的功能,比如Path.of()
和Files.readString()
, Files.writeString()
等方法。Java 8中需要用旧的方法来实现相同的功能。
Java 11 示例:
var path = Path.of("data.txt");
var content = Files.readString(path);
Files.writeString(path, "Example");
转换为Java 8:
Path path = Paths.get("data.txt");
byte[] bytes = Files.readAllBytes(path);
String content = new String(bytes, StandardCharsets.UTF_8);
Files.write(path, "Example".getBytes(StandardCharsets.UTF_8));
7. Lambda 表达式的增强
Java 11 在 lambda 表达式的局部变量上允许使用 var
关键字,使得可以在lambda表达式中为参数显式声明类型注解。Java 8 支持 lambda 表达式,但不支持在其中使用 var
。
Java 11 示例:
(BinaryOperator<Integer>) (var x, var y) -> x + y;
转换为Java 8:
(BinaryOperator<Integer>) (Integer x, Integer y) -> x + y;
8. Optional 的增强
Java 11 引入了 Optional.isEmpty()
方法,以提供对 Optional 对象是否为空的更直观的检查。Java 8 中并没有这个方法,可以通过 !Optional.isPresent()
来替代。
Java 11 示例:
Optional<String> optional = Optional.of("test");
boolean isEmpty = optional.isEmpty();
转换为Java 8:
Optional<String> optional = Optional.of("test");
boolean isEmpty = !optional.isPresent();
9. try-with-resources 的改进
Java 9 优化了 try-with-resources 语句,使得可以在 try 语句中直接使用之前已经声明的变量。Java 8 要求资源必须在 try 语句内声明。
Java 11 示例:
BufferedReader reader = new BufferedReader(new FileReader("test.txt"));
try (reader) {
return reader.readLine();
}
转换为Java 8:
try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
return reader.readLine();
}
10. HTTP Client API
Java 11 引入了全新的 HTTP Client API 以支持 HTTP/2. Java 8 中没有这样的API,通常需要使用 HttpURLConnection
或引入第三方库如 Apache HttpClient。
Java 11 示例:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://example.com"))
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
转换为Java 8:
URL url = new URL("http://example.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
InputStream inputStream = connection.getInputStream();
String response = new BufferedReader(new InputStreamReader(inputStream))
.lines().collect(Collectors.joining("\n"));