@Shadow
@Shadow
注解用于在 Mixin
类中声明一个对目标类中成员(字段或方法)的引用。这允许你从 Mixin
的方法中访问目标类的私有(private)或保护(protected)成员。
用法
访问字段
要访问目标类中的一个字段,你可以在 Mixin
中声明一个带有 @Shadow
注解的同名同类型的字段。
示例:
目标类:
java
public class Player {
private boolean onGround;
}
Mixin:
java
@Mixin(Player.class)
public abstract class PlayerMixin {
@Shadow private boolean onGround;
@Inject(method = "jump", at = @At("HEAD"))
private void onJump(CallbackInfo ci) {
if (this.onGround) {
// ...
}
}
}
现在你可以在 onJump
方法中访问 onGround
字段了。
访问方法
同样地,你也可以用 @Shadow
来访问目标类中的方法。
示例:
目标类:
java
public class Block {
protected void dropItems() {
// ...
}
}
Mixin:
java
@Mixin(Block.class)
public abstract class BlockMixin {
@Shadow protected abstract void dropItems();
@Inject(method = "destroy", at = @At("TAIL"))
private void onDestroy(CallbackInfo ci) {
this.dropItems();
}
}
注意,@Shadow
方法必须是 abstract
的。
prefix
属性
有时,你的 Mixin
类可能需要一个与目标类中字段或方法同名的成员。为了避免命名冲突,你可以使用 prefix
属性。Mixin 会自动为你添加上前缀。
示例:
java
@Mixin(Example.class)
public class ExampleMixin {
@Shadow(prefix = "shadow$")
private int value; // This will shadow the 'value' field in Example.class
private int value; // This is a new field specific to the mixin
public void someMethod() {
this.value = 1; // Accesses the mixin's own 'value' field
this.shadow$value = 2; // Accesses the shadowed 'value' field from the target class
}
}
final
字段
如果目标字段是 final
的,你需要在 @Shadow
注解的字段上也加上 final
修饰符。
java
@Shadow final private int score;
如果你想修改一个 final
字段,你需要使用 @Mutable
注解和 @Shadow
一起。
java
@Mixin(Example.class)
public abstract class ExampleMixin {
@Mutable
@Shadow
private final int score;
// constructor or other methods to modify score
}
现在你就可以在你的 Mixin
方法中修改 score
的值了。
匿名内部类
@Shadow
也可以用于匿名内部类,但这通常比较复杂,因为匿名类没有名字。你需要使用特殊的语法来定位它们。