@Optional 可以被传入一个方法参数以声明它是可选的。
调用方法时可选参数可被省略:

CraftTweaker 的 IFurnaceManager:

java
Copy
    @ZenMethod
    void remove(IIngredient output, @Optional IIngredient input);

MCFurnaceManager (实现)

java
Copy
    @Override
    public void remove(IIngredient output, @Optional IIngredient input) {
        if(output == null)
            throw new IllegalArgumentException("output cannot be null");

        recipesToRemove.add(new ActionFurnaceRemoveRecipe(output, input));
    }

技术上,在实现中你不需要 @Optional,但如果你确定的话你也可以加上它。 你现在可以使用以下任意方式调用这个方法:

java
Copy
furnace.remove(output); //输入将被设置为 null(空值)
furnace.remove(output, input);

省略的参数被插入了什么值?

Link to 省略的参数被插入了什么值

根据注解类型,被插入的是 0falsenull

基本类型会是 0(除了布尔值,它会是 false,所以技术上 0 是最好的)
所有的对象都会是 null

使用注解成员

Link to 使用注解成员

成员类型默认值
成员
value
类型
string
默认值
""
成员
methodClass
类型
java.lang.Class
默认值
Optional.class
成员
methodName
类型
string
默认值
"getValue"

可选参数也支持默认值。
如果你想提供默认值,你可以通过传入 value 成员代表参数的字符串来实现。

如果你只想要基本类型,则你已设置。

java
Copy
@ZenMethod
public static void print(@Optional("heyho") String value) {
    CraftTweakerAPI.logError(value);
}


@ZenMethod
public static void print3(@Optional("1") int value) {
    CraftTweakerAPI.logError(String.valueOf(value));
}

如果你想要一个不是编译时实例的默认对象或默认基本类型(所有注解成员都需要编译时实例!),你可以设置其他两个成员:这会调用传入的(静态)方法 methodClass.methodName(value) 以替换参数。 如果找不到对应方法,将报错并插入 null。

java
Copy
@ZenMethod
public static void print2(@Optional(value = "minecraft:iron_ingot", methodClass = Optionals.class, methodName = "getFromString") IItemStack value) {
    print(value.getDisplayName());
}


public static IItemStack getFromString(String value) {
    return BracketHandlerItem.getItem(value, 0);
}

什么参数可以被注解?

Link to 什么参数可以被注解

所有的参数都可以被注解,但你需要记住注解的参数需要在末尾,因此技术上虽然可行,但调用方法将会失败:

java
Copy
myMethod(@Optional String name, int number)

只使用一个 int 参数调用此方法时将始终失败!