前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大人,时代变了!使用 Java 16 或 Kotlin 更好的进行插件或模组开发

大人,时代变了!使用 Java 16 或 Kotlin 更好的进行插件或模组开发

作者头像
HikariLan贺兰星辰
发布2022-10-27 09:57:20
5620
发布2022-10-27 09:57:20
举报
文章被收录于专栏:HikariLan's BlogHikariLan's Blog

本文最后更新于 450 天前,其中的信息可能已经有所发展或是发生改变。

大人,时代变了!使用 Java 16 或 Kotlin 更好的进行插件或模组开发

声明:本文章中 Java 8 至 Java 16 以来变化的内容整理自 这个网站,您可以访问该网站以了解更多新版本 Java 的更改

简洁起见,对于某些不重要,或者对开发意义不大的更新,本文并未列出

前言

从很久很久以前,Minecraft 的社区开发者们就开始使用包含了全新的 Stream 库和 Lambda 语句的 Java 8 进行插件或者模组开发,时至今日,Java 8 已成为开发者、服主、玩家使用最多的 Java 版本 —— 或许仍将持续下去,至少对那些忠于旧版本的人们来说。但对于勇于探索新生的冒险者们来说,他们不得不开始正视一个新的拦路虎,亦或者说一种新的机遇 —— 那就是 Java 16。

从 Java Edition 1.17(正确的来说,是 21w19a)开始,Minecraft 需要 Java 16 或更新版本才能运行。对于这个最新更改,人们别无选择,只能慢慢接受 —— 对于玩家和服主来说,可能只是卸载一个旧版本,安装一个新版本的事情。但对于开发者来说,很显然我们需要知道更多。

本文的存在就是这个意义,我们将介绍从 Java 8 开始到 Java 16 重要的开发内容更新,并附带这些更新在以 Java 8 为运行时的 Kotlin 是如何处理的,以帮助开发者们能够更快的适应和享受新的 Java 或者 Kotlin 带来的更高的开发效率。

什么样的开发者适合切换到 Java 16

对于 Minecraft 开发者而言,由于兼容性,很显然并不是所有的开发者都能够切换到 Java 16 进行开发。以普遍理性而言,这些开发者应当可以切换到 Java 16 进行开发:

  • 所有面向 Minecraft 1.17 或更高版本进行开发的模组/插件开发者
  • 面向 Minecraft 1.13+ 的 Bukkit 插件开发者

为什么使用 Kotlin

Kotlin(JVM) 作为一个基于 JVM 平台的开发语言,为开发者们提供了更加舒适的开发方式,收到了很多开发者的追捧。对于 Kotlin 来说,由于其可以基于 Java 8 运行,因此在大多数情况下无需进行更多更改,只需要在模组或插件内包含一个 Kotlin 的标准库,便可以享受 Kotlin 带来的便捷开发。

本文关于 Kotlin 的示例基于 Java 8 运行时,这意味着,某些 JVM 平台更新可能已经在 Kotlin 同样可用,比如 Kotlin 已经添加了对 JVM 中 Record Class 的支持,但我们并不使用这些版本的代码,而将仍旧选择基于 Java 8 运行时时的解决方案 —— 当然,基于更高版本 Java 运行时的 Kotlin 仍旧可以支持这些代码。

请注意,本文章的主题并不是 Kotlin,因此 Kotlin 内容仅作为对比,并非主要内容。

正文:Java 16 到底带来了什么更改?

使用 var 更简洁的创建局部变量

In Java 8

代码语言:javascript
复制
final List<String> list = new ArrayList<>();

In Java 16

代码语言:javascript
复制
final var list = new ArrayList<String>();

注意,var 仅支持局部变量,而不支持全局变量。

In Kotlin

代码语言:javascript
复制
val list = arrayListOf<String>()

使用 Record Class 更方便的创建数据传输对象

In Java 8

代码语言:javascript
复制
public class Point{

    private int x;
    private int y;

    public Point(int x, int y){
        this.x = x;
        this.y = y;
    }

    public x(){
        return x;
    }

    public y(){
        return y;
    }
}

Point point = new Point(1, 2);
point.x(); // returns 1
point.y(); // returns 2

In Java 16

代码语言:javascript
复制
record Point(int x, int y) { }

var point = new Point(1, 2);
point.x(); // returns 1
point.y(); // returns 2

In Kotlin

代码语言:javascript
复制
// With additional toString, hashCode function,like @Data in Lombok
data class Point(val x : Integer,val y : Integer)

var point = Point(1, 2)
point.x // return 1
point.y // return 2

增强的 switch

In Java 8

代码语言:javascript
复制
int numLetters;
switch (day) {
    case MONDAY, FRIDAY, SUNDAY:
        numLetters = 6;
        break;
    case TUESDAY:
        numLetters = 7;
        break;
    default:
        String s = day.toString();
        numLetters = s.length();
}

In Java 16

代码语言:javascript
复制
int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    default      -> {
      String s = day.toString();
      int result = s.length();
      yield result;
    }
};

In Kotlin

代码语言:javascript
复制
var numLetters = when (day){
        MONDAY, FRIDAY, SUNDAY -> 6
        TUESDAY -> 7
        else ->{
            var s = day.toString()
            var result = s.length
            result
        }
    }

使用密封类以限定继承的子类

In Java 8

代码语言:javascript
复制
// No solution

In Java 16

代码语言:javascript
复制
public abstract sealed class Shape
    permits Circle, Rectangle {...}

public class Circle extends Shape {...} // OK
public class Rectangle extends Shape {...} // OK
public class Triangle extends Shape {...} // Compile error

// No need for default case if all permitted types are covered
double area = switch (shape) {
    case Circle c    -> Math.pow(c.radius(), 2) * Math.PI
    case Rectangle r -> r.a() * r.b()
};

In Kotlin

代码语言:javascript
复制
package pkg.a

sealed class Shape

class Circle : Shape() {...} // OK
class Rectangle : Shape() {...} // OK


package pkg.b

class Triangle : Shape() {...} // Compile error

// No need for default case if all permitted types are covered
var area = when (shape) {
    is Circle -> Math.pow(shape.radius(), 2) * Math.PI
    is Rectangle -> shape.a() * shape.b()
}

文本块

In Java 8

代码语言:javascript
复制
String html = "<html>\n" +
                "    <body>\n" +
                "        <p>Hello, world</p>\n" +
                "    </body>\n" +
                "</html>\n";

In Java 16

代码语言:javascript
复制
String html = """
            <html>
                <body>
                    <p>Hello, world</p>
                </body>
            </html>
            """;

In Kotlin

代码语言:javascript
复制
var html = """
            <html>
                <body>
                    <p>Hello, world</p>
                </body>
            </html>
            """

当变量为 null 时提供更加详细友好的 NullPointerException 描述

In Java 8

代码语言:javascript
复制
a.b.c.i = 99;
---
Exception in thread "main" java.lang.NullPointerException

In Java 16

代码语言:javascript
复制
a.b.c.i = 99;
---
Exception in thread "main" java.lang.NullPointerException:
      Cannot read field "c" because "a.b" is null

模式匹配 instanceof 以省略必要的显式类型转换

In Java 8

代码语言:javascript
复制
if (obj instanceof String) {
    String s = (String) obj;
    if(s.length() > 5){
        System.out.println("obj is a String with more than 5 characters: " + s.toUpperCase());
    }
}

In Java 16

代码语言:javascript
复制
if (obj instanceof String s && s.length() > 5) {
    System.out.println("obj is a String with more than 5 characters: " + s.toUpperCase());
}

In Kotlin

代码语言:javascript
复制
if (obj is String && obj.length > 5) {
    println("obj is a String with more than 5 characters: " + obj.uppercase(Locale.getDefault()))
}

接口中允许私有方法

In Java 8

代码语言:javascript
复制
// Not allowed

In Java 16

代码语言:javascript
复制
public interface some {
    private void doSomething(){
        // do something
    }
}

In Kotlin

代码语言:javascript
复制
interface some {
    private fun doSomething() {
        // do something
    }
}

更方便的将 Stream 收集为 List

In Java 8

代码语言:javascript
复制
List<String> result =
  Stream.of("one", "two", "three")
    .filter(s -> s.length() == 3)
    .collect(Collectors.toList());

In Java 16

代码语言:javascript
复制
List<String> result =
  Stream.of("one", "two", "three").stream()
    .filter(s -> s.length() == 3)
    .toList();

In Kotlin

代码语言:javascript
复制
var result =
  Stream.of("one", "two", "three")
    .filter(s -> s.length() == 3)
    .toList()

为 String 添加了更多有用的方法

In Java 16

代码语言:javascript
复制
"           ".isBlank(); // will return true

Stream<String> lines = "1\n2\n3\n4".lines(); // will return Stream ["1", "2", "3", "4"]

"a".repeat(4); // will return "aaaa"

"\u2000 hello \u2000".strip(); // will return "hello"

为集合添加了更多易于使用的工厂方法

In Java 8

代码语言:javascript
复制
Set<Integer> mySet = new HashSet<>();
mySet.add(1);
mySet.add(2);
mySet.add(3);
List<Integer> myList = new ArrayList<>();
myList.add(1);
myList.add(2);
myList.add(3);
Map<String, Integer> myMap = new HashMap<>();
myMap.put("one",1);
myMap.put("two",2);

In Java 16

代码语言:javascript
复制
Set<Integer> mySet = Set.of(1, 2, 3);
List<Integer> myList = List.of(1, 2, 3);
Map<String, Integer> myMap = Map.of("one", 1, "two", 2);

In Kotlin

代码语言:javascript
复制
var mySet = setOf(1, 2, 3)
var myList = listOf(1, 2, 3)
var myMap = mapOf("one" to 1, "two" to 2)

除此之外,支持更多平台,支持 TLS 1.3,全新的 jlink 工具,HTML5 标准的 Javadoc,更强大的 ZGC 等特性都将可以在全新的 Java 16 中体验到。

值得一提的是,Java 8 中内置的 JavaScript 解析器 Nashron ,jjs 工具,Java EE,Unsafe::defineAnonymousClass(),基本数据类型的包装对象的构造函数都在 Java 16 中被移除或是废弃。

最后。为什么不现在就切换到 Java 16,来体验更高效的开发呢?

(完)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-7-27 2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 大人,时代变了!使用 Java 16 或 Kotlin 更好的进行插件或模组开发
    • 前言
      • 什么样的开发者适合切换到 Java 16
        • 为什么使用 Kotlin
          • 正文:Java 16 到底带来了什么更改?
            • 使用 var 更简洁的创建局部变量
            • 使用 Record Class 更方便的创建数据传输对象
            • 增强的 switch
            • 使用密封类以限定继承的子类
            • 文本块
            • 当变量为 null 时提供更加详细友好的 NullPointerException 描述
            • 模式匹配 instanceof 以省略必要的显式类型转换
            • 接口中允许私有方法
            • 更方便的将 Stream 收集为 List
            • 为 String 添加了更多有用的方法
            • 为集合添加了更多易于使用的工厂方法
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档