本帖最后由 无敌三脚猫 于 2023-3-2 22:57 编辑
https://www.mcbbs.net/thread-874131-1-1.html
这边我看过很多次了,最近才发现一个问题
跟没接触过cnpc的人解释一下,这个mod有一个脚本系统,可以用Nashorn引擎写js脚本
上述脚本中出现了一个奇怪的东西复制代码咦?这哪儿来的无参构造?
如果在java里写new net.minecraftforge.event.ServerChatEvent(),会显示构造函数 ServerChatEvent()未定义
因为ServerChatEvent真的只有这一个构造函数复制代码可能不同版本具体的参数不一样,不过这不重要,这个类确实是在每个版本都没有无参构造,所以Nashorn是怎么把它new出来的?而且没有报错(我写过了)
不关nashorn的事,是forge干的
https://www.mcbbs.net/thread-874131-1-1.html
这边我看过很多次了,最近才发现一个问题
跟没接触过cnpc的人解释一下,这个mod有一个脚本系统,可以用Nashorn引擎写js脚本
上述脚本中出现了一个奇怪的东西
- var Event=Java.type("net.minecraftforge.event.ServerChatEvent");
- var event=new Event();
如果在java里写new net.minecraftforge.event.ServerChatEvent(),会显示构造函数 ServerChatEvent()未定义
因为ServerChatEvent真的只有这一个构造函数
- public ServerChatEvent(EntityPlayerMP player, String message, ITextComponent component)
- {
- super();
- this.message = message;
- this.player = player;
- this.username = player.getGameProfile().getName();
- this.component = component;
- }
不关nashorn的事,是forge干的
Unsafe 的 allocateInstance 方法?没用过 Nashorn 盲猜的。
本帖最后由 Neige 于 2023-3-2 13:23 编辑
我拿bukkit的AsyncPlayerChatEvent试了一下,不行,会报they do not match any of its method signatures
你这很怪
我拿bukkit的AsyncPlayerChatEvent试了一下,不行,会报they do not match any of its method signatures
你这很怪
Nashorn 调用无参构造会报出
TypeError: Can not create new object with constructor ClassA with the passed arguments; they do not match any of its method signatures.
Unsafe.allocateInstance 可以做到强制实例 但从我这里来看Nashorn 没有采用这个
也许是版本不同
TypeError: Can not create new object with constructor ClassA with the passed arguments; they do not match any of its method signatures.
Unsafe.allocateInstance 可以做到强制实例 但从我这里来看Nashorn 没有采用这个
也许是版本不同
本帖最后由 无敌三脚猫 于 2023-3-2 22:26 编辑
刚刚,我改我mod的字节码,改出了一句new ServerChatEvent()
new net/minecraftforge/event/ServerChatEvent
dup
invokespecial net/minecraftforge/event/ServerChatEvent <init> ()V
pop
然后,没有崩溃,也没有报错
我感觉forge可能干了什么不得了的事情,在游戏启动过程中强行给所有事件都加上了无参构造,但是为什么呢?
算了不管那个了,我现在想问问@Hueihuea是怎么发现这一神奇特性的
好了不用问了
美味的曲奇 发表于 2023-3-2 17:43
Nashorn 调用无参构造会报出
TypeError: Can not create new object with constructor ClassA with the pas ...
刚刚,我改我mod的字节码,改出了一句new ServerChatEvent()
new net/minecraftforge/event/ServerChatEvent
dup
invokespecial net/minecraftforge/event/ServerChatEvent <init> ()V
pop
然后,没有崩溃,也没有报错
我感觉forge可能干了什么不得了的事情,在游戏启动过程中强行给所有事件都加上了无参构造,但是为什么呢?
好了不用问了
翻了一下 Forge 事件的实现,还真是。
用 ASM 给每个 Event 加了一个默认的无参构造器,因为 Forge 注册事件监听器的实现,就是用反射无参创建一个事件,好用 getListenerList 实例方法获取这个类的 ListenerList,往这个列表加监听器才算注册。和那个教程的写法一样。
但为啥不直接在 EventBus 记录一个 Map<Class<?>, ListenerList> 呢?怪哦。
用 ASM 给每个 Event 加了一个默认的无参构造器,因为 Forge 注册事件监听器的实现,就是用反射无参创建一个事件,好用 getListenerList 实例方法获取这个类的 ListenerList,往这个列表加监听器才算注册。和那个教程的写法一样。
但为啥不直接在 EventBus 记录一个 Map<Class<?>, ListenerList> 呢?怪哦。
本帖最后由 无敌三脚猫 于 2023-3-3 10:19 编辑
用ASM加无参构造就已经很怪了,明明可以直接写进源码的
我后来想到了一点,可能是因为有些final的成员变量,所以不能直接写无参构造
youyihj 发表于 2023-3-2 22:08
翻了一下 Forge 事件的实现,还真是。
用 ASM 给每个 Event 加了一个默认的无参构造器,因为 Forge 注册事 ...
我后来想到了一点,可能是因为有些final的成员变量,所以不能直接写无参构造