For 循环和异常执行的更广泛问题

问题描述 投票:0回答:1

我目前正在用 Java 编写 Minecraft Mod,在正确实现异常方面遇到一些问题。

我在课堂上尝试了以下不同的事情:

  • 在我使用地图而不是列表之前
  • 使用 Try and Catch 方法
  • For循环获取ID

我想要的是,如果您使用 register 方法,并且任何一个 If 语句为真,它都会抛出异常,但它根本没有。就像 if 语句总是假的一样。

这是课程:

public class SoulType {
    private static final List<SoulType> SOUL_TYPES = new ArrayList<>();

    private final String id;
    private final String displayName;
    private final SoulTypeRarities rarity;
    private final double corruption;
    private double strength;

    private SoulType(String id, String displayName, SoulTypeRarities rarity, double corruption, double strength) {
        this.id = id;
        this.displayName = displayName;
        this.rarity = rarity;
        this.corruption = corruption;
        this.strength = strength;
    }

    public static List<SoulType> getSoulTypes() { // Neue Getter-Methode
        return SOUL_TYPES;
    }

    public String getId() {
        return id;
    }

    public String getDisplayName() {
        return displayName;
    }

    public SoulTypeRarities getRarity() {
        return rarity;
    }

    public Double getCorruption() {
        return corruption;
    }

    public Double getStrength() {
        return strength;
    }

    public void setStrength(double newStrength) {
        this.strength = newStrength;
    }

    public void addStrength(double addStrength) {
        this.strength += addStrength;
    }

    public static SoulType register(String id, String displayName, SoulTypeRarities rarity, double corruption, double strength) throws IllegalArgumentException {
        double minCorruption = 0;
        double maxCorruption = 2;
        double minStrength = 0;
        double maxStrength = 5;
        if (corruption < minCorruption || corruption > maxCorruption) {
            throw new IllegalArgumentException("Corruption must be between " + minCorruption + " and " + maxCorruption + " .");
        }
        if (strength < minStrength || strength > maxStrength) {
            throw new IllegalArgumentException("Strength must be between " + minStrength + " and " + maxStrength + " .");
        }
        SoulType newType = new SoulType(id, displayName, rarity, corruption, strength);
        SOUL_TYPES.add(newType);
        for (SoulType soulType : SOUL_TYPES) {
            if (soulType.getId().equals(id)) {
                throw new IllegalArgumentException("SoulType with id '" + id + "' already exists.");
            }
        }
        return newType;
    }

    public static SoulType fromId(String id) {
        for (SoulType soulType : SOUL_TYPES) {
            if (soulType.getId().equals(id)) {
                return soulType;
            }
        }
        throw new IllegalArgumentException("SoulType with id '" + id + "' not found.");
    }
}

这也是调用方法的类:

public class SoulTypes {
    public static final SoulType HARMONY = SoulType.register("harmony", "Harmonie", SoulTypeRarities.COMMON, 0.0, 1.0);
    public static final SoulType BOLLWERK = SoulType.register("bollwerk", "Bollwerk", SoulTypeRarities.RARE, 0.8, 1.5);
}

一段时间后,我还遇到了关于另一个类的问题,如果您使用我创建的自定义命令,它会执行类中的方法。但是当我从 Map 切换到 List 后,似乎 for 循环根本没有执行。

这是课程:

public class SoulCMDProcedure {
    public static void execute(Entity entity) {
        if (entity == null)
            return;
        if (entity instanceof Player player && !player.level().isClientSide()) {
            player.displayClientMessage(Component.literal("Registered Soul Types:"), false);
            for (SoulType soulType : SoulType.getSoulTypes()) {
                ChatFormatting rarityColor = switch (soulType.getRarity()) {
                    case COMMON -> ChatFormatting.WHITE;
                    case UNCOMMON -> ChatFormatting.GREEN;
                    case RARE -> ChatFormatting.BLUE;
                    case EPIC -> ChatFormatting.DARK_PURPLE;
                    case LEGENDARY -> ChatFormatting.GOLD;
                };
                ChatFormatting resetColor = ChatFormatting.RESET;
                String message = String.format("- %s (ID: %s, Rarity: %s, Corruption: %.2f, Strength: %.2f)", soulType.getDisplayName(), soulType.getId(), rarityColor + soulType.getRarity().toString() + resetColor, soulType.getCorruption(),
                        soulType.getStrength());
                player.displayClientMessage(Component.literal(message), false);
            }
        }
    }
}

这里还有使用上述方法的类:

@Mod.EventBusSubscriber
public class SoulCommand {
    @SubscribeEvent
    public static void registerCommand(RegisterCommandsEvent event) {
        event.getDispatcher().register(Commands.literal("soul")

                .then(Commands.literal("types").then(Commands.literal("all").executes(arguments -> {
                    Level world = arguments.getSource().getUnsidedLevel();
                    double x = arguments.getSource().getPosition().x();
                    double y = arguments.getSource().getPosition().y();
                    double z = arguments.getSource().getPosition().z();
                    Entity entity = arguments.getSource().getEntity();
                    if (entity == null && world instanceof ServerLevel _servLevel)
                        entity = FakePlayerFactory.getMinecraft(_servLevel);
                    Direction direction = Direction.DOWN;
                    if (entity != null)
                        direction = entity.getDirection();

                    SoulCMDProcedure.execute(entity);
                    return 0;
                }))));
    }
}

我希望有人能帮助我解决这个问题。

java minecraft minecraft-forge
1个回答
0
投票

我认为问题出在你的 register() 方法中:

SOUL_TYPES.add(newType);
    for (SoulType soulType : SOUL_TYPES) {
        if (soulType.getId().equals(id)) {
            throw new IllegalArgumentException("SoulType with id '" + id + "' already exists.");
        }

这总是会抛出异常,因为您在检查灵魂类型是否具有当前 ID 之前添加了该 ID。除此之外,在测试代码时,如果损坏/强度超出范围,它会正确抛出错误,否则不会。

我对Java中的switch语句不太熟悉,所以我会让其他人回答第二个问题。

© www.soinside.com 2019 - 2024. All rights reserved.