Лекция 3: Generics, Lambda, Enum
Generics, lambda/Supplier, method reference, enum
Эти конструкции Java выглядят сложно с первого взгляда, но в моддинге они повторяются из файла в файл. Стоит разобраться один раз.
Generics (угловые скобки)
<Item> после класса говорит, с каким типом он работает:
DeferredRegister<Item> ITEMS = ...; // реестр для предметов
DeferredRegister<Block> BLOCKS = ...; // реестр для блоков
RegistryObject<Item> PINKYLITE = ...; // ссылка на конкретный предмет
Без <Item> реестр принимал бы что угодно, и ошибки всплыли бы только при запуске игры. С generics компилятор ловит проблемы заранее.
Lambda-выражения и Supplier
Lambda позволяет записать функцию прямо на месте, без отдельного класса. Сравните:
// Полная запись
Supplier<Item> supplier = new Supplier<Item>() {
@Override
public Item get() {
return new Item(new Item.Properties());
}
};
// Lambda — то же самое, но в одну строку
Supplier<Item> supplier = () -> new Item(new Item.Properties());
При регистрации Forge не создаёт объект сразу. Вместо этого вы даёте ему лямбду — инструкцию "создай, когда будешь готов":
ITEMS.register("pinkylite_crystal", () -> new Item(new Item.Properties()));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// "создай Item, когда я попрошу"
() -> читается как "когда вызовут, сделай вот это".
Method reference (ссылка на метод)
Если лямбда только вызывает один метод, можно записать короче через :::
// Lambda
modEventBus.addListener(event -> this.commonSetup(event));
// Method reference — то же самое, короче
modEventBus.addListener(this::commonSetup);
this::commonSetup читается как "метод commonSetup этого объекта". Java сама подставит аргументы.
В главном классе мода это выглядит так:
public RinovaMod(FMLJavaModLoadingContext context) {
IEventBus modEventBus = context.getModEventBus();
modEventBus.addListener(this::commonSetup); // ← method reference
}
Enum
Enum — набор заранее известных значений. Четыре редкости предмета, шесть направлений блока, три типа урона. Если вариантов конечное количество, это enum:
public enum Rarity {
COMMON, // белый
UNCOMMON, // жёлтый
RARE, // голубой
EPIC // фиолетовый
}
new Item.Properties().rarity(Rarity.UNCOMMON); // жёлтое название