用户:MashKJo/1.21.1模组开发教程/3.注册:修订间差异

无编辑摘要
无编辑摘要
无编辑摘要
第35行: 第35行:
== 遍历注册表 ==
== 遍历注册表 ==
使用for-each循环即可。
使用for-each循环即可。
== 注册对象 ==
=== 注册对象资源键 ===
没错,所有注册对象也同样需要一个ResourceKey<?>,以便于在注册表中查找它们。注册对象资源键的泛型参数即为注册对象的类型,如Item、Block等;其registryName为对应注册表资源键的location,而注册对象资源键的location,即为喜闻乐见的通常意义上的“注册名”了,如minecraft:apple、minecraft:barrier等。
ResourceKey<?> key = ResourceKey.create(resourceKey, location);
    //一般是通过这个方式得到某个注册对象的资源键,resourceKey即为注册对象对应注册表的ResouceKey。
    //从这里可以看出,ResourceKey在某种程度上有点“继承”的概念。
另外,ResourceKey是有内部缓存的,也就是说我们可以用==运算符来比较2个ResourceKey。
通过注册对象资源键,我们可以便捷地在注册表中查询注册对象。
=== Holder ===
在实际代码中,注册对象多数情况下并非直接出现的,而是被一层Holder<?>包裹起来,如在涉及到有关附魔对象的代码时,一般出现的都是Holder<Enchantment>而非直接的Enchantment。
我们可以直接用Holder#value来获取封装起来的值,也可以通过Holder#direct、Registry#wrapAsHolder、Registry#getHolderOrThrow来获取一个Holder。注意:Holder#direct获取的实际上是一个实现了Holder<?>的record:Holder.Direct,正如其名,我们直接把一个注册对象传入进去,直接包装成一个Holder,对value()的调用时机没有任何限制。然而还存在另一个实现类:Holder.Reference,后两者获取的实际类型便是它,牵扯到注册表的一些机制,它是有点类似于惰性加载的(但加载的时机实际不受Modder控制),所以过早地(指在RegisterEvent发布前)调用它的value()(即forward reference)方法会导致NPE崩游戏,且会提示Trying to access unbounded value...。通过调用#kind可以知道一个Holder的实际类型。
Holder的意义在于更好地对注册对象进行管理,如:判断其是否属于某个标签(Tag)。
行政员、​优秀编辑者、​界面管理员、​监督员、​管理员、​小部件编辑者
3,417

个编辑