本帖最后由 贺兰兰 于 2020-11-30 22:45 编辑
前言
什么是 Kotlin
为什么选择 Kotlin 进行 Java 应用程序开发
Kotlin是一门简洁,安全,互操作性强,工具友好的现代计算机程序语言,通过使用Kotlin进行程序开发,能够“大大减少样板代码的数量”,“避免空指针异常等整个类的错误”,“充分利用JVM的现有库”。
什么是 TabooLib
TabooLib是一款以内置依赖形式加载的轻量级Bukkit插件开发库,诞生于2017年,现其主要开发者为Bkm016和IzzelAliz
为什么选择TabooLib进行Bukkit插件开发
TabooLib内置了许多高效的工具,可以让你快速创建GUI/书本菜单,高效地创建指令监听,自动注册事件监听器,通过自带的Hikari连接池快速地连接到MySQL数据库,便捷地处理玩家数据,配置文件喝本地化文件......使用TabooLib,能够大幅度减少插件开发周期,提升插件代码质量。
Kotlin+TabooLib能爆出怎样的火花
TabooLib原生支持使用Kotlin作为其开发语言,前者可为后者自动提供JVM平台库,避免了插件自带Kotlin JVM平台库导致的依赖冲突和编译文件大小膨胀的问题。
本文定位
本文适合那些有一定Java和Bukkit开发基础的,希望学习使用Kotlin和TabooLib进行Bukkit插件开发的开发人员们阅读。而对于那些仍然希望使用Java的开发者,您可以通过阅读此文章获得一些有关TabooLib的使用帮助——TabooLib当然也原生支持Java
搭建环境
部署 TabooLib-SDK
你可以通过以下方式下载并部署TabooLib-SDK
复制代码
复制代码
可选的,您可通过以下配置内容修改TabooLib版本和TabooLib Loader版本
复制代码
可选的,您可以通过将文件后缀明为jar的文件放入项目根目录中的libs(如无请自行创建)以加载本地依赖文件;或直接在此处添加Maven/Gradle依赖
复制代码
至此,您已完成TabooLib-SDK的部署,不出意外的话,您的主类应当呈现出以下内容:
复制代码
开始了解插件主类代码结构
可选的分号
复制代码
在插件主类中,首先映入我们眼帘的应当是包声明和类导入声明,这些在Java中再常见不过的东西放到Kotlin中却体现了Kotlin之于Java一个重大的不同点: 句尾分号可选,所谓可选,并不是说向Python等语言一样不存在分号作为每行代码的分割,而是代表着当代码仅占一行,没有必要通过分号表示分割关系时,可以不添加分号,这意味着:
复制代码
是完全可被接受(但在Kotlin中并不倡导)的语法。当然,当一行代码希望表示多个语句时,分号就是必要的了,如:
复制代码
区别于“类”声明的“对象”声明
复制代码
对于一个Java Coder来说,包生命和导入声明下面大部分情况下应该就是类声明了,但是,为什么我没有看到class关键字,是看到了一个从未看过的object关键字?
Kotlin是有class关键字的,你完全可以尝试将object改为class,编译器并不会报错,事实上,你也不会看到任何问题。
我们都知道,“Object”指的是对象,由此我们可以猜测出object关键字描述的应当是一个“对象”——事实上,它是一个单例对象。
在Java中,我们往往需要为类单独应用单例模式,以确保该类不会被初始化超过一次,并且希望通过相应操作得到唯一一个对象实例。在Kotlin中,这种繁琐的设计流程被直接简化到了“对象”声明上,只需使用object声明,我们便可以快速得到一个单例对象及其实例。
在主类使用单例对象有何好处
如果你刚刚上手Bukkit开发,那么你可能曾犯过这样一个致命的错误: 当某方法需要提供一个Plugin对象时,你试图直接new一个主类传进去,自以为这样就可以满足方法的要求了——编译时没有报错,但当运行时你却收到了一个错误:插件主类实例只能有一个——很显然,Bukkit的插件主类对象也是一个单例。因此,将主类设计为object的,可以避免让我们设计一个getInstance方法获取主类实例,继而直接传入一个object对象给方法(事实上,在Kotlin中方法被称作函数),如:
复制代码
通过以上方式快速设计一个继承BukkitRunnable的匿名内部类,并像调用静态方法一样调用主类的非静态方法。
需要注意的是,MyExamplePlugin.plugin是由TabooLib提供的Getter,用于获取一个org.bukkit.plugin.java.JavaPlugin(即Bukkit插件主类)实例
Java互操作
Kotlin和Java代码时可以互操作的,在Java中试图获取一个object对象实例,只需调用自动生成的INSTANCE字段,即可获得一个Kotlin对象实例。这意味着,当你正在使用一个TabooLib的Kotlin主类实例,但又希望使用Java编写BukkitRunnable时,写法是这样的:
复制代码
小心!没有static
Kotlin给我们带来了方便的对象,但同时也夺走了一个Java中重要的东西: 静态方法。这意味着,通常情况下,你不能(实际上也不推荐)创建一个静态方法。取而代之的,你可以创建一个对象,在其中声明函数以调用。
当然,如果你一定需要使用静态方法,那么你可以通过向Kotlin函数声明'@JvmStstic'注解以静态调用,如:
复制代码
Kotlin的类继承语法
复制代码
此处表示对象MyExamplePlugin继承了Plugin类,并调用其空构造函数。
可以发现,Kotlin的构造器并非在类内单独声明,而是直接在类声明上表示。往后我们将会接触更多有关Kotlin的构造器的使用方法。
Kotlin的函数声明语法
复制代码
与Java的方法声明语法不同,Kotlin采用fun关键字以声明一个函数,其声明格式大致为
复制代码
其中,当不希望返回任何值时,返回值处和其前的冒号可省略不写。
override修饰符
是的,Kotlin将Java的@Override注解的职能直接搬到了修饰符层面上:开发者通过使用override修饰符来声明函数覆盖自其超类。
嘿,不是void
你可能认为空返回值意味着void,但实际上,在Kotlin,空返回值实际上是Unit,也就是说,上述函数声明等同于
复制代码
类型后置语法
你可能已经发现了,在Kotlin中,变量类型是后置的,而不是Java那样的类型前置。
这也就是说,Java中的
复制代码
在Kotlin中应当写作
复制代码
由于在Kotlin中,函数默认的可见度为public,因此无需显式声明函数公开。
至此,你已经了解了Kotlin得主类结构及相关Kotlin语言语法。
编译插件
当插件编写完成,我们需要编译插件时,可直接运行gradle jar指令,或通过IDE运行Gradle指令编译。

编译后的jar文件会被存放在./build/libs文件夹内
插件太大了吗
你可能会发现,编译后的插件文件远大于它正常情况下的大小,这是因为编译后的插件文件除了我们自己编写的内容外,还包含了TabooLib Loader,用于自动下载和管理TabooLib本体和库文件(包括Kotlin运行时库)。这么做的好处是我们不需要自己在插件内包含Kotlin运行时库,TabooLib会在第一次运行是帮我们自动下载至服务端,极大的缩减了插件大小。
至此,你已经完成了本章的所有内容,下一章中,我们会继续深入Kotlin语法,同时开始接触TabooLib提供给我们的便携功能。
前言
什么是 Kotlin
Kotlin是一种在Java虚拟机上运行的静态类型编程语言。它主要是由俄罗斯圣彼得堡的JetBrains开发团队所发展出来的编程语言,其名称来自于圣彼得堡附近的科特林岛。虽然与Java语法并不兼容,但在JVM环境中Kotlin被设计成可以和Java代码相互运作,并可以重复使用如Java集合框架等的现有Java引用的函数库。
为什么选择 Kotlin 进行 Java 应用程序开发
Kotlin是一门简洁,安全,互操作性强,工具友好的现代计算机程序语言,通过使用Kotlin进行程序开发,能够“大大减少样板代码的数量”,“避免空指针异常等整个类的错误”,“充分利用JVM的现有库”。
什么是 TabooLib
TabooLib是一款以内置依赖形式加载的轻量级Bukkit插件开发库,诞生于2017年,现其主要开发者为Bkm016和IzzelAliz
为什么选择TabooLib进行Bukkit插件开发
TabooLib内置了许多高效的工具,可以让你快速创建GUI/书本菜单,高效地创建指令监听,自动注册事件监听器,通过自带的Hikari连接池快速地连接到MySQL数据库,便捷地处理玩家数据,配置文件喝本地化文件......使用TabooLib,能够大幅度减少插件开发周期,提升插件代码质量。
Kotlin+TabooLib能爆出怎样的火花
TabooLib原生支持使用Kotlin作为其开发语言,前者可为后者自动提供JVM平台库,避免了插件自带Kotlin JVM平台库导致的依赖冲突和编译文件大小膨胀的问题。
本文定位
本文适合那些有一定Java和Bukkit开发基础的,希望学习使用Kotlin和TabooLib进行Bukkit插件开发的开发人员们阅读。而对于那些仍然希望使用Java的开发者,您可以通过阅读此文章获得一些有关TabooLib的使用帮助——TabooLib当然也原生支持Java
搭建环境
本教程使用的TabooLib版本为v5.36,TabooLib Loader版本为v2.6
TabooLib开发者和本文作者均推荐使用Jetbrains IntelliJ IDEA作为首选的集成开发环境进行开发
部署 TabooLib-SDK
TabooLib-SDK 是TabooLib官方推出的插件开发模板,内置预配置好的TabooLib所需的Gradle构建列表文件,通过使用TabooLib-SDK你可以快通过简单修改配置文件以快速开始TabooLib插件开发。当前,TabooLib不支持Maven构建
你可以通过以下方式下载并部署TabooLib-SDK
- 前往Github下载TabooLib-SDK: 点击直接下载最新版本
- 解压TabooLib-SDK文件夹,可选的,您可以先将文件夹名称改为您的项目名以方便记录
- 编辑settings.gradle,将 ExamplePlugin 改为您的项目名称
- rootProject.name = 'ExamplePlugin'
- 编辑build.gradle,将 io.izzel.taboolib.example 改为您的主类所在包名,将 1.0.0 改为您的插件版本号
- group = 'io.izzel.taboolib.example'
- version = '1.0.0'
可选的,您可通过以下配置内容修改TabooLib版本和TabooLib Loader版本
- taboolib {
- tabooLibVersion = '5.36'
- loaderVersion = '2.6'
- classifier = null
- }
可选的,您可以通过将文件后缀明为jar的文件放入项目根目录中的libs(如无请自行创建)以加载本地依赖文件;或直接在此处添加Maven/Gradle依赖
- dependencies {
- compile 'ink.ptms.core:v11600:11600:all'
- compile 'org.jetbrains.kotlin:kotlin-stdlib'
- compileOnly fileTree(dir: 'libs', includes: ['*.jar'])
- }
- 编辑 ./src/main/resources/plugin.yml 文件,将 authors: ['坏黑'] 改成你自己的名字以免坏黑盗取你的插件(划掉)
- 通过IDE重构项目包名为上方设置的group值,并重构项目主类名为上方设置的rootProject.name值(亦可直接前往./src/main/java文件夹内手动修改)
- 导入项目至IDE,等待Gradle Sync完成
至此,您已完成TabooLib-SDK的部署,不出意外的话,您的主类应当呈现出以下内容:
- package kim.minecraft.example
- import io.izzel.taboolib.TabooLib
- import io.izzel.taboolib.loader.Plugin
- object MyExamplePlugin : Plugin() {
- override fun onLoad() {
- // override onLoad()
- }
- override fun onEnable() {
- // override onEnable()
- }
- override fun onDisable() {
- // override onDisable()
- }
- }
开始了解插件主类代码结构
可选的分号
- package kim.minecraft.example
- import io.izzel.taboolib.TabooLib
- import io.izzel.taboolib.loader.Plugin
在插件主类中,首先映入我们眼帘的应当是包声明和类导入声明,这些在Java中再常见不过的东西放到Kotlin中却体现了Kotlin之于Java一个重大的不同点: 句尾分号可选,所谓可选,并不是说向Python等语言一样不存在分号作为每行代码的分割,而是代表着当代码仅占一行,没有必要通过分号表示分割关系时,可以不添加分号,这意味着:
- import io.izzel.taboolib.TabooLib;
- import io.izzel.taboolib.loader.Plugin;
是完全可被接受(但在Kotlin中并不倡导)的语法。当然,当一行代码希望表示多个语句时,分号就是必要的了,如:
- import io.izzel.taboolib.TabooLib;import io.izzel.taboolib.loader.Plugin;
区别于“类”声明的“对象”声明
- object MyExamplePlugin {} //为方便分条说明暂时去除了部分元素,仅保留基本声明
对于一个Java Coder来说,包生命和导入声明下面大部分情况下应该就是类声明了,但是,为什么我没有看到class关键字,是看到了一个从未看过的object关键字?
Kotlin是有class关键字的,你完全可以尝试将object改为class,编译器并不会报错,事实上,你也不会看到任何问题。
我们都知道,“Object”指的是对象,由此我们可以猜测出object关键字描述的应当是一个“对象”——事实上,它是一个单例对象。
在Java中,我们往往需要为类单独应用单例模式,以确保该类不会被初始化超过一次,并且希望通过相应操作得到唯一一个对象实例。在Kotlin中,这种繁琐的设计流程被直接简化到了“对象”声明上,只需使用object声明,我们便可以快速得到一个单例对象及其实例。
在主类使用单例对象有何好处
如果你刚刚上手Bukkit开发,那么你可能曾犯过这样一个致命的错误: 当某方法需要提供一个Plugin对象时,你试图直接new一个主类传进去,自以为这样就可以满足方法的要求了——编译时没有报错,但当运行时你却收到了一个错误:插件主类实例只能有一个——很显然,Bukkit的插件主类对象也是一个单例。因此,将主类设计为object的,可以避免让我们设计一个getInstance方法获取主类实例,继而直接传入一个object对象给方法(事实上,在Kotlin中方法被称作函数),如:
- object : BukkitRunnable() {
- override fun run() {
- MyExamplePlugin.plugin.logger.info("test")
- }
- }.runTaskAsynchronously(MyExamplePlugin.plugin)
通过以上方式快速设计一个继承BukkitRunnable的匿名内部类,并像调用静态方法一样调用主类的非静态方法。
需要注意的是,MyExamplePlugin.plugin是由TabooLib提供的Getter,用于获取一个org.bukkit.plugin.java.JavaPlugin(即Bukkit插件主类)实例
Java互操作
Kotlin和Java代码时可以互操作的,在Java中试图获取一个object对象实例,只需调用自动生成的INSTANCE字段,即可获得一个Kotlin对象实例。这意味着,当你正在使用一个TabooLib的Kotlin主类实例,但又希望使用Java编写BukkitRunnable时,写法是这样的:
- new BukkitRunnable() {
- @Override
- public void run() {
- MyExamplePlugin.INSTANCE.getPlugin().getLogger().info("test");
- }
- }.runTaskAsynchronously(MyExamplePlugin.INSTANCE.getPlugin());
小心!没有static
Kotlin给我们带来了方便的对象,但同时也夺走了一个Java中重要的东西: 静态方法。这意味着,通常情况下,你不能(实际上也不推荐)创建一个静态方法。取而代之的,你可以创建一个对象,在其中声明函数以调用。
当然,如果你一定需要使用静态方法,那么你可以通过向Kotlin函数声明'@JvmStstic'注解以静态调用,如:
- @JvmStatic
- fun staticFunction() {
- }
Kotlin的类继承语法
- object MyExamplePlugin : Plugin() {}
此处表示对象MyExamplePlugin继承了Plugin类,并调用其空构造函数。
可以发现,Kotlin的构造器并非在类内单独声明,而是直接在类声明上表示。往后我们将会接触更多有关Kotlin的构造器的使用方法。
Kotlin的函数声明语法
- override fun onLoad() {
- // override onLoad()
- }
与Java的方法声明语法不同,Kotlin采用fun关键字以声明一个函数,其声明格式大致为
- fun 函数名称(参数1 : 参数类型,参数2: 参数类型,...): 返回值类型
其中,当不希望返回任何值时,返回值处和其前的冒号可省略不写。
override修饰符
是的,Kotlin将Java的@Override注解的职能直接搬到了修饰符层面上:开发者通过使用override修饰符来声明函数覆盖自其超类。
嘿,不是void
你可能认为空返回值意味着void,但实际上,在Kotlin,空返回值实际上是Unit,也就是说,上述函数声明等同于
- override fun onLoad(): Unit {
- // override onLoad()
- }
类型后置语法
你可能已经发现了,在Kotlin中,变量类型是后置的,而不是Java那样的类型前置。
这也就是说,Java中的
- public Location getLocation(Location loc) {}
在Kotlin中应当写作
- fun getLocation(loc: Location): Location {}
由于在Kotlin中,函数默认的可见度为public,因此无需显式声明函数公开。
至此,你已经了解了Kotlin得主类结构及相关Kotlin语言语法。
编译插件
当插件编写完成,我们需要编译插件时,可直接运行gradle jar指令,或通过IDE运行Gradle指令编译。

编译后的jar文件会被存放在./build/libs文件夹内
插件太大了吗
你可能会发现,编译后的插件文件远大于它正常情况下的大小,这是因为编译后的插件文件除了我们自己编写的内容外,还包含了TabooLib Loader,用于自动下载和管理TabooLib本体和库文件(包括Kotlin运行时库)。这么做的好处是我们不需要自己在插件内包含Kotlin运行时库,TabooLib会在第一次运行是帮我们自动下载至服务端,极大的缩减了插件大小。
至此,你已经完成了本章的所有内容,下一章中,我们会继续深入Kotlin语法,同时开始接触TabooLib提供给我们的便携功能。
贺兰tql
海螺yyds
Kt好难 爬了
海螺yyds
Kt好难 爬了
45gfg9 发表于 2020-9-30 13:28
贺兰tql
海螺yyds
kt不难,用得挺香
如果你有java基础,通过对比学习或许学的更快
而且,java源码 cv 到idea kotlin会自动转化(不一定完全正确)
是taboolib教程!爷青结
个人感觉kt简化过头了,写起来不是很舒服。
Java虽然有些地方略微繁琐,但最近几个Java版本都做了改进,感觉都不错,有协程就更好了
Java虽然有些地方略微繁琐,但最近几个Java版本都做了改进,感觉都不错,有协程就更好了
贺兰太强惹ummm [水ummmm]
666666666666666
66666666666666
我竟然看到了错别字,两个
尽量客观解开了回家看了该回家看了
古holy发了一个i李玉刚
ui偶一哦噗i哦怕
hklhklkl;l'lll
速度放缓的法国海军的复古怀旧风格
写的太棒了,想问问还有第二篇吗呜呜呜