简体   繁体   中英

Exception Handling a switch method

I'm trying to get a program I made to ask someone for a number between 1 and 13 in order to get them to make a selection. I'm trying to figure out how to handle if they want to be contrarian and enter a non-valid number or a character or string. Here's what I have so far...

try {
        attackingUnit = selectUnit(input.nextInt());
        attackerUnitName = attackingUnit.getUnitName();
    } catch (NullPointerException e) {
        System.out.println("Invalid option, please pick a valid option\n");
        showUnitSelection();
        attackingUnit = selectUnit(input.nextInt());
        attackerUnitName = attackingUnit.getUnitName();
}

Here's the method I'm using for a making the selection itself:

private static Unit selectUnit(int selection) {

    switch (selection) {
        case 1:
            return Unit.GreatSwords;
        case 2:
            return Unit.BlackOrcs;
        case 3:
            return Unit.Bestigor;
        case 4:
            return Unit.ChaosChosen;
        case 5:
            return Unit.MenAtArms;
        case 6:
            return Unit.Executioners;
        case 7:
            return Unit.GraveGuard;
        case 8:
            return Unit.Retributors;
        case 9:
            return Unit.StormVermin;
        case 10:
            return Unit.SwordMasters;
        case 11:
            return Unit.TombGuard;
        case 12:
            return Unit.WildWoodRangers;
        case 13:
            return Unit.Hammerers;
    }

    return null;
}

I'm pretty sure I'm not doing this right, if you don't mind I'd like to hear some suggestions to consider.

I think code will look much prettier if you do it in this way:

public enum Unit{

        GreatSwords(1),
        BlackOrcs(2),
        Bestigor(3),
        ChaosChosen(4),
        MenAtArms(5),
        Executioners(6),
        GraveGuard(7),
        Retributors(8),
        StormVermin(9),
        SwordMasters(10),
        TombGuard(11),
        WildWoodRangers(12),
        Hammerers(13)

        private int index;

        public int getIndex() {
            return this.index;
        }

        public static getUnitByIndex(int index) throws IllegalArgumentException {
            return Stream.of(values())
            .filter(unit -> unit.getIndex() == index)
            .findFirst()
            .orElseThrow(() -> new IllegalArgumentException("Invalid value");
        }

}

The idea over here would be to avoid nulls, therefore the best option would be to make a default case that return Unit.Unknown if the switch statement does not match anything. Then you can check if the input equals Unit.Unknown and if it does tell the user that it is invalid.

To do this, First add in a "Unknown" member to the Unit enum.

Then add in a default case to your switch statement like this:

     default:
        return Unit.Unknown;

Then in your original code change it to this:

       attackingUnit = selectUnit(input.nextInt());
    attackerUnitName = attackingUnit.getUnitName();
    //check if its valid
    if(attackerUnitName==Unit.Unknown){
    //unit is unknown ,tell the user the input was invalid
    } else {
    //input was valid, do what you want to do
    }

Your switch code would be like with default case-

    private static Unit selectUnit(int selection) {

        switch (selection) {
            case 1:
                return Unit.GreatSwords;
            case 2:
                return Unit.BlackOrcs;
            case 3:
                return Unit.Bestigor;
            case 4:
                return Unit.ChaosChosen;
            case 5:
                return Unit.MenAtArms;
            case 6:
                return Unit.Executioners;
            case 7:
                return Unit.GraveGuard;
            case 8:
                return Unit.Retributors;
            case 9:
                return Unit.StormVermin;
            case 10:
                return Unit.SwordMasters;
            case 11:
                return Unit.TombGuard;
            case 12:
                return Unit.WildWoodRangers;
            case 13:
                return Unit.Hammerers;
 default:throw new IllegalArgumentException(""Invalid option, please pick a valid option\n");
        }

    }

Your handling code would be like -

try {
        attackingUnit = selectUnit(input.nextInt());
        attackerUnitName = attackingUnit.getUnitName();
    } catch (IllegalArgumentException e) {
        System.out.println(e.getMessage);
        showUnitSelection();
        attackingUnit = selectUnit(input.nextInt());
        attackerUnitName = attackingUnit.getUnitName();
}

Try this. Using exception handling for simple validation is an expensive operation, although it will work just fine.

attackingUnit = null;
while(attackingUnit == null){
   System.out.println("Invalid option, please pick a valid option\n");
   showUnitSelection();
   attackingUnit = selectUnit(input.nextInt());   
}

attackerUnitName = attackingUnit.getUnitName();

Update: Modify you method to include default case (as per @SteelToe suggestion)

private static Unit selectUnit(int selection) {

switch (selection) {
    case 1:
        return Unit.GreatSwords;
    case 2:
        return Unit.BlackOrcs;
    case 3:
        return Unit.Bestigor;
    case 4:
        return Unit.ChaosChosen;
    case 5:
        return Unit.MenAtArms;
    case 6:
        return Unit.Executioners;
    case 7:
        return Unit.GraveGuard;
    case 8:
        return Unit.Retributors;
    case 9:
        return Unit.StormVermin;
    case 10:
        return Unit.SwordMasters;
    case 11:
        return Unit.TombGuard;
    case 12:
        return Unit.WildWoodRangers;
    case 13:
        return Unit.Hammerers;
    default:
        return Unit.Unknown;

  }


}

And do this:

attackingUnit = Unit.Unknown;
while(attackingUnit == Unit.Unknown){
   System.out.println("Invalid option, please pick a valid option\n");
   showUnitSelection();
   attackingUnit = selectUnit(input.nextInt());   
}

attackerUnitName = attackingUnit.getUnitName();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM