Minecraft(我的世界)中文论坛

 找回密码
 注册(register)
查看: 3549|回复: 27

[插件开发教程] [教程系列]利用Annotation与反射实现更加整洁易用的子命令

[复制链接]
发表于 2016-12-9 17:51:23 | 显示全部楼层 |阅读模式

您尚未登录,立即登录享受更好的浏览体验!

您需要 登录 才可以下载或查看,没有帐号?注册(register)

x
本帖最后由 RecursiveG 于 2016-12-18 06:40 编辑

论坛竟然没有滑稽表情,差评!

                               
登录/注册后可看大图

大家平时写子命令都是都是用的switch或者if吧,但是这种方法在子命令多的情况下特别蛋疼,代码很乱,各种嵌套,影响阅读。
今天我讲给各位介绍利用Annotation+反射实现更加方便清晰易用的子命令。
什么是Annotation?   百度去
什么是反射?    百度去

接下来,我将以一个/xxx命令为梨子,来介绍利用Annotation写子命令

首先,你需要准备的是:
  电脑
  大脑
  双手
  滑稽

                               
登录/注册后可看大图


打开我们的IDE,我创建一个工程,并且完成包,类的,创建。并且在plugin.yml里注册xxx命令。
他看起来是这样的额

                               
登录/注册后可看大图


接下来,我们在onEnable方法里注册命令,并创建命令类。

                               
登录/注册后可看大图



一切看起来似乎很正常!
接下来才是正文!
我们创建一个Annotation类,就叫他SubCommand

                               
登录/注册后可看大图



@interface是定义Annotation类的关键字

@Target(ElementType.METHOD) 指的是用于方法的声明
@Retention(RetentionPolicy.RUNTIME) 指的是运行时加载Annotation到JVM中
default 表示这个成员的默认值。
不懂没关系,记住就行。
然后我们在里面定义了3个成员,后面会用到。
回到我们的命令方法,我们添加一个无参数的判断,输出所有子命令。
如图:

                               
登录/注册后可看大图


这里我们遍历了本类的方法,判断是否有SubCommand注释,如果有,获取这个方法的注释并拼接帮助并发送消息。
很多人问为什么要遍历本类方法?因为我们把子命令写在了这个类,下面看下去你就知道了。
然后,有帮助还不行,还有执行子命令啊,于是,如图:

                               
登录/注册后可看大图


我们同样遍历本类方法,判断SubCommand注释,并且判断注释中的cmd是否和输入的参数相等,相等就使用反射执行此方法,并return true退出方法。
然后我们再加个找不到子命令的提示

                               
登录/注册后可看大图


最后,完整的onCommand()方法是这样的:

好了,命令轮子造完了,现在我们几乎不需要再去动他了,我们只需要在下面添加命令就行了。@SubCommand(cmd="子命令内容",arg="参数介绍",des="命令介绍")
public void 方法名字随便写(Player p,String args[]){
//执行此子命令
}
为什么参数是Player p和String args[]呢?
因为,我们上面利用反射执行的时候传进来就是这两个参数,而我们也需要这2个参数啊,不然子命令怎么知道执行者和其他的参数?
方法名随意,因为靠的是上面的@SubCommand注释来判断的
然后我们添加2个字命令进行测试:

                               
登录/注册后可看大图

由于我们的命令帮助是靠遍历Annotation自动生成的,我们也不需要去改动onCommand方法
我们来测试下:

                               
登录/注册后可看大图


很棒是不是
而且代码清晰可读性高,添加子命令快速,自动生成帮助。

好了,教程就到这里
求人气求回复

禁止转载!禁止转载!

评分

参与人数 11人气 +15 金粒 +80 收起 理由
754503921 -1 图片已挂,请补全后私信版主撤销评分.
萌菌团 + 1 楼主你太帅了~
innc + 1 楼主你太帅了~
shugen + 1 给膝盖
1582952890 + 2 楼主你太帅了~
z25096708 + 2 + 35 原来修饰符还有这用。。。学习了.
RecursiveG + 1 已加入教程全家桶
rtz43 + 2 + 35 我还很好奇标注是干啥的原来是拿来反射的.
hcrgm1 + 2 MCBBS有你更精彩~
810587921 + 2 很棒的作品!
wansi + 1 + 11 向大佬低头

查看全部评分

发表于 2016-12-10 11:33:09 | 显示全部楼层
前排,支持!
回复

使用道具 举报

发表于 2016-12-10 18:27:17 来自手机 | 显示全部楼层
反射使效率降低了不少
回复

使用道具 举报

 楼主| 发表于 2016-12-10 19:12:30 | 显示全部楼层
耗子 发表于 2016-12-10 18:27
反射使效率降低了不少

这只是命令而已,效率问题不大
我觉得还是美观易用最重要
switch/if写出来各种嵌套看的辣眼睛。
回复

使用道具 举报

发表于 2016-12-10 19:45:46 | 显示全部楼层
jebme 发表于 2016-12-10 19:12
这只是命令而已,效率问题不大
我觉得还是美观易用最重要
switch/if写出来各种嵌套看的辣眼睛。 ...

与其写个教程,不如写个API

评分

参与人数 1人气 +1 收起 理由
z25096708 + 1 喜欢吃鱼的老鼠!

查看全部评分

回复

使用道具 举报

发表于 2016-12-12 02:15:27 | 显示全部楼层
耗子 发表于 2016-12-10 19:45
与其写个教程,不如写个API

这就涉及到一个名言了
授人以鱼不如授人以渔←_←
当然,像什么用到nms之类的,代码多的,还是鱼好了
回复

使用道具 举报

发表于 2016-12-12 23:45:42 | 显示全部楼层
有人写过类似的但并没有分享。。
可以考虑写成API前置嘛
回复

使用道具 举报

发表于 2016-12-15 09:07:04 | 显示全部楼层
我觉得还是发教程好,自己写比调用的好多了
回复

使用道具 举报

发表于 2016-12-15 17:37:37 | 显示全部楼层
只是一个用不用的问题,反射更适合用在其他类里
回复

使用道具 举报

发表于 2016-12-15 20:03:37 | 显示全部楼层
虽说反射降低了效率 但是可以把反射后的结果 比如Method 先存起来 下次就直接用了
Bukkit的事件系统 在registerEvents之后 似乎也是这样做的 对效率的影响没那么大了 起码不会再遍历一遍了
回复

使用道具 举报

发表于 2016-12-15 20:25:20 | 显示全部楼层
反射卡卡卡……………………(省略1000个卡)…………卡,好的,反射比直接调用卡1000倍左右,这也是为什么Mod服带不了特别多的人,如果你要forClass的话还要更卡
当然如果你只是调用指令的话没问题,但是不建议在Java中过度使用反射,你要想啃语言糖就去用scala
回复

使用道具 举报

发表于 2016-12-15 23:00:56 | 显示全部楼层
如果不考虑Java6的支持,为何不直接使用MethodHandle呢= =
回复

使用道具 举报

发表于 2017-1-25 14:51:34 | 显示全部楼层
我有应该问题,子命令下的子命令该如何解决?
比如/am automsg enable
回复

使用道具 举报

 楼主| 发表于 2017-1-25 15:27:50 | 显示全部楼层
awt2003 发表于 2017-1-25 14:51
我有应该问题,子命令下的子命令该如何解决?
比如/am automsg enable

这个直接在子命令执行里判断参数吧

评分

参与人数 1人气 +1 收起 理由
awt2003 + 1 很棒的作品!

查看全部评分

回复

使用道具 举报

发表于 2017-6-22 13:33:46 | 显示全部楼层
叶米柯 发表于 2016-12-15 20:25
反射卡卡卡……………………(省略1000个卡)…………卡,好的,反射比直接调用卡1000倍左右,这也是为什么Mo ...

MOD服带不了特别多人与反射有啥关系?

难道是MOD服大量使用反射?  MOD在使用还是FORGE在使用?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册(register)

本版积分规则

Archiver|小黑屋|Mcbbs.net ( 京ICP备15023768号-1 ) | 手机版本

GMT+8, 2018-10-21 18:24 , Processed in 0.076242 second(s), 7 queries , Memcache On.

"Minecraft"以及"我的世界"为Mojang Synergies AB的商标。本站与Mojang以及微软公司没有从属关系。

© 2010-2017 我的世界中文论坛 版权所有。本站原创图文内容版权属于原创作者,未经许可不得转载。

快速回复 返回顶部 返回列表