0

EDIT: Sorry I didn't make this clear earlier, I already wrote this program and completed it using nested if's, what I'm trying to do now, is practice writing exception classes, I do understand that this way is way less efficient than the way I have previously wrote it, but I am trying to do it this way to further learn more about java. Thanks again.

Basically the only strings you're allowed to type are, "print, sortfirst, sortlast, sortgrade" and I can't figure out how to write this without a winded if statement.

the class I have written is;

public class WrongCommandException extends Exception
{
public WrongCommandException (String message)
{
    super(message);
}
}

would i have to construct arguments in this class or would I do it in my main class inside the while loop reading off user input?

GonePhisin
  • 45
  • 6
  • how are you reading the input? command line args? java.util.Scanner? –  Nov 29 '17 at 06:57
  • You can use `Arrays.asList("print", "sortfirst" etc).contains(message)` simply to avoid the if. But I think it's a bad idea to do what you're trying to do anyway. – Andy Turner Nov 29 '17 at 07:00
  • @JarrodRoberson I'm using the scanner, this is an old project that I already submitted and passed, just using it to practice different kind of exception handling now – GonePhisin Nov 29 '17 at 07:33

4 Answers4

1

The problem with your approach is that you're proposing adding a new way of making your code fail at runtime. And a runtime failure when you're trying to handle some other runtime failure (i.e. the reason you're throwing the exception in the first place) is a bad idea.

Make it impossible to use an invalid input at compile time. If you only want to accept a finite number of inputs, either:

  • Make specific subclasses of the exception for each of the inputs;
  • Provide static factory methods in the exception class, each one constructing an exception for a particular input;
  • Create an enum, one value for each of the valid inputs, and pass an instance to the constructor.
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • Yep, use an enum here - perfect use case for this, and exactly what I was going to suggest. Though, on a side note - it's not clear to me why this would be an exception if those are the supported commands... – Krease Nov 29 '17 at 07:05
0

Binding your business inside exception is a bad idea/design.

Check your business where you needed and just use this exception if user entered wrong thing.

Put the conditions inside your while loop where you checking against user. That way you can reuse this exception throughout your project.

And coming to the part of nested if's, make an array with predefined values and check the entered value inside the array or not with a simple loop. That way you can reduce if's.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
0

Generally it's not a good idea to solve the problem of wrong input with throwing an exception because it stops the normal work of the program during runtime. There are better ways like asking for another input in while loop or simply printing some kind of error message when input is not correct.

If you still think it's a best idea in your situation I suggest assigning inputted value to String s and check it with

(if "print".equals(s) || "sortfirst".equals(s) || ...)) 
    { throw new WrongCommandException("Your message here") }

When creating your exception class it's good to create a constructor taking a String argument which is going to be shown when your exception is thrown.

But again, the better idea in your situation is to make all the required checks in while loop in a main() method, not with with throwing an exception nor with providing checks in the body of your exception.

Przemysław Moskal
  • 3,551
  • 2
  • 12
  • 21
  • 1
    The program I wrote is already finished and that's how I initially wrote it with a loop and nested ifs for acceptable commands, however now I'm working on exceptions, I should have made that clear that I know it's much less efficient, but more of a learning program than effective thank you, I will look over this when I get back on my computer – GonePhisin Nov 29 '17 at 16:59
  • @GonePhisin I think that it would be a good idea to edit your question to contain additional informations you gave in this comment to provide people reading it better understanding of your problem. Wish you all the best. – Przemysław Moskal Nov 29 '17 at 22:10
0

Business logic does not go inside an exception, but having a very explicit exception message is crucial to having a maintainable system.

public InvalidCommandException extends FormattedRuntimeException
{
    public InvalidCommandException(@Nonnull final String command)
    {
        super("(%s) is not a valid command. Valid command are [print, sortfirst, sortlast, sortgrade]!", command);
    }
}

Here is FormattedRuntimeException

/**
 * This is a convenience facade class to enable simple message creation as the String.format()
 * facilities instead of manually building strings to pass in as a message.
 * <p/>
 */
public class FormattedRuntimeException extends RuntimeException
{
    protected FormattedRuntimeException(@Nonnull final String format, @Nonnull Object... args)
    {
        super(String.format(format, args));
    }

    protected FormattedRuntimeException(@Nonnull final Throwable cause, @Nonnull String format, @Nonnull Object... args)
    {
        super(String.format(format, args), cause);
    }

    /**
     * This no-arg constructor is hidden specifically to keep people from using it
     */
    private FormattedRuntimeException()
    { /* keep people from using "anonymous" instances */ }

    /**
     * This Exception only constructor is hidden specifically to keep people from using it
     */
    private FormattedRuntimeException(final Exception e)
    { /* keep people from using "anonymous" instances */ }
}