User Tools

Site Tools


zh_cn:tutorial:accesswideners

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
zh_cn:tutorial:accesswideners [2021/10/25 10:14] – [Access Wideners] solidblockzh_cn:tutorial:accesswideners [2024/08/12 04:11] (current) jeffreyg1228
Line 1: Line 1:
 ====== 访问加宽 ====== ====== 访问加宽 ======
  
-访问加宽(Access wideners)提供了一种放宽类、方法、字段访问权限的方式。访问加宽类似于著名的 Access Transformers.+访问加宽(Access wideners)提供了一种放宽类、方法、字段访问权限的方式。访问加宽类似于著名的 Access Transformers
  
-访问加宽应该**仅在**使用 Mixin 无法实现时使用。目前有以下两种情景 Mixin 无法做到: +访问加宽可代替 Mixin。目前有以下两种情景 Mixin 无法做到: 
-  * 需要访问一个(包内)私有类,尤其是为了 @Shadow 修饰或在 Mixin 类内访问一个字段或方法。 +  * 需要访问 package 或 private 级别的类,尤其是为了 @Shadow 修饰(shadowing)或访问 Mixin 里的字段或方法。 
-  * 需要重写使用 final 修饰的子类。 +  * 需要重写使用 final 修饰的子类,或将其子类化。 
-    * 在你考虑重写使用 final 修饰的方法之前使用注入器等方法修改。 +    * 如果你想用 package 或 private 级别的构造函数子类,使用访问加宽是个不错的选择
-    * 如果你想为一个包含私有构造方法的创建子类,wideners 是个不错的选择+
  
-为了让 access widener 造成的的变化显示在反编译的源代码中,请运行 ''genSources'' gradle任务。+为了让访问加宽造成的的变化显示在反编译的源代码中,请运行 ''genSources'' Gradle 任务,然后在 IDE 中重新加载 Gradle 项目。 
 + 
 +注意:与 Mixin 访问器不同,访问加宽不适用于模组的源代码
  
 ===== 需求 ===== ===== 需求 =====
Line 16: Line 17:
 ===== 文件格式 ===== ===== 文件格式 =====
  
 +需要在您的模组里使用特定的文件格式,来声明访问权限修改。为了帮助 IDE,您应该使用 ''.accesswidener'' 文件扩展名。
  
-需要在你的模组里包含一个声明修改访问权限的特殊文件,为了帮助,你应该在IDE中使用 ''.accesswidener'' 文件扩展名。 +该文件首行应该遵循下述格式,''命名空间'' 应该始终设置为 ''named'',而不是模组命名空间。Loom 将会重新映射模组和访问加宽文件到中间名
- +
-该文件首行应该遵循下述格式,''命名空间'' 应该与你模组源码使用混淆命名空间匹配,通常是 ''named''。 Loom 将会为你重新映射 access widener 文件,使其更改为 ''intermediary''。如果你使用自定义的 ''RemapJarTask'',设置 ''remapAccessWidener'' 为 ''true'' 来确保上述行为发生+
  
 <code [enable_line_numbers="true"]> <code [enable_line_numbers="true"]>
-accessWidener v1 <命名空间>+accessWidener v2 <命名空间>
 </code> </code>
  
-**再次提醒,命名空间应该在你使用 yarn 命名时设置为 ''named'', 使用中间名命名时设置为 ''intermediary''。**+**再次强调,命名空间在绝大多数情况下应该是 ''named''。**
  
-Access widener 文件允许使用空行和和以 # 开头的注释。+访问加宽文件允许使用空行和和以 # 开头的注释。
  
 <code [enable_line_numbers="true"]> <code [enable_line_numbers="true"]>
-# 这样的注释是支持的,当它被放在行尾也是这样的+# 这样的注释和行尾注释都是支持的
 </code> </code>
  
-任何空白字符都作为 access widener 文件的分隔符,推荐制表符 tab。+任何空作为访问加宽文件的分隔符,推荐制表符 tab。
  
 类名应该使用 / 分隔,而不是 . 类名应该使用 / 分隔,而不是 .
  
-对于内部类,应该使用 ''$'' 来代替 ''/''+对于内部类,应该使用 ''$'' 而不是 ''/''
  
 == 类 == == 类 ==
  
-类的访问权限可以通过指定 访问权 和 类称 来改变,就像第一行定义命名空间那样。+类的访问权限可以通过指定访问权和类名来改变,就像第一行定义命名空间那样。
  
 <code [enable_line_numbers="true"]> <code [enable_line_numbers="true"]>
-<访问权>   class   <类名>+<访问权>   class   <类名>
 </code> </code>
  
-  - 访问权可以是 //accessible// 或 //extendable//+  - 访问权可以是 //accessible// 或 //extendable//
  
 == 方法 == == 方法 ==
  
-可以通过指定访问权限、类名、方法名称和方法描述符来改变方法访问权,就像上面定义的映射命名空间一样。+可以通过指定访问权限、类名、方法名称和方法描述符来改变方法访问权,就像上面定义的映射命名空间一样。
  
 <code [enable_line_numbers="true"]> <code [enable_line_numbers="true"]>
-<access>   method   <className>   <methodName>   <methodDesc>+<访问权限>   method   <类名>   <方法名>   <方法描述符>
 </code> </code>
  
-  - access 可以是 //accessible// 或 //extendable// +  - 访问权限可以是 //accessible// 或 //extendable// 
-  - classname 是拥有者类 +  - 类名是拥有方法的类
-  - methodName 是方法名称 +
-  - methodDesc 是方法描述符+
  
 == 字段 == == 字段 ==
  
-字段的访问权可以通过指定访问权、类名、字段名称和字段描述符来修改,就像上面定义的映射命名空间一样。+字段的访问权可以通过指定访问权、类名、字段名称和字段描述符来修改,就像上面定义的映射命名空间一样。
  
 <code [enable_line_numbers="true"]> <code [enable_line_numbers="true"]>
-<access>   field   <className>   <fieldName>   <fieldDesc>+<访问权限>   field   <类名>   <字段名>   <字段描述符>
 </code> </code>
  
-  - access 可以是 //accessible// 或 //mutable// +  - 访问权限可以是 //accessible// 或 //mutable// 
-  - className 是拥有者类 +  - 类名是拥有字段的类
-  - fieldName 是字段名称 +
-  - fieldDesc 是字段描述符+
  
-===== 访问权变更 =====+===== 访问权限修改 =====
  
 === Extendable(可继承) === === Extendable(可继承) ===
  
-需要继承最终类或者覆盖最终方法时,用 extendable。+需要继承类或者重写方法时,用 extendable。
  
-  * 类将会改成 public 并移除 final 修饰符 +  * 类将变为 public 并移除 final 修饰符 
-  * 方法会改成 protected 并移除 final 修饰符+  * 方法将变为 protected 并移除 final 修饰符
  
 将方法改为 extendable 的同时也会使类变为 extendable。 将方法改为 extendable 的同时也会使类变为 extendable。
Line 88: Line 84:
 === Accessible(可访问) === === Accessible(可访问) ===
  
-需要访问另一个类的类、字段方法时,用 accessible。+需要访问另一个类及其字段方法时,用 accessible。
  
   * 类将变为 public   * 类将变为 public
-  * 方法将变为 public,若为 private,还会变为 final+  * 方法将变为 public,且 private 方法将用 final 修饰
   * 字段将会变为 public   * 字段将会变为 public
  
Line 101: Line 97:
  
   * 字段将会移除 final 修饰符   * 字段将会移除 final 修饰符
 +
 +若想让一个 private final 字段既 accessible 又 mutable,需要两条指令。
  
 ===== 指定文件位置 ===== ===== 指定文件位置 =====
Line 131: Line 129:
 ... ...
 </code> </code>
 +
 +===== 验证文件 =====
 +默认情况下,不存在的访问加宽条目将被忽略。
 +在 Loom 的最新版本中,您可以运行 ''gradlew validAccessWidener'' 来检查访问加宽文件中指定的所有类、字段和方法是否存在。
 +
 +错误消息可能有点隐晦。例如,如果您在指定字段时犯了错误,错误不会说明问题是字段名称还是类型。例如,如果它说找不到字段 “''fooI''”,则可能意味着没有名为 ''foo'' 的字段,或者它存在但不是 ''int'' (''I'')。
 +
 +===== V2 更改 =====
 +
 +在访问加宽 v2 版本中,添加了以 ''transitive-*'' 为前缀的关键字:
 +
 +  * ''transitive-accessible''
 +  * ''transitive-extendable''
 +  * ''transitive-mutable''
 +
 +它们与常规的、无前缀的变体不同,但它们也适用于依赖于此的模组。
zh_cn/tutorial/accesswideners.1635156842.txt.gz · Last modified: 2021/10/25 10:14 by solidblock