Kailua Bum
Kailua Bum

Reputation: 1368

Java: Proper way to throw and catch an exception to validate input

Im writing a program for homework where I need to validate user input and then create an object and add it to an array list. i have included just what i think is the relevant code, but im a beginner for sure so let me know if there is something else you need to see.

I have the user enter a string, then check to see if its a double. if its not a double, i throw an exception that i created

     try{
        price = Double.parseDouble(strPrice);
     }
     catch(NumberFormatException nfe){
        CDException cde = new CDException();
        cde.setMessage("Price must be a number,\nCannot create CD");
        throw cde;
     }

after making sure that it is a number, in my other class i check to make sure it is in the range that i want. (non negative in this case) then create an object with the value

public void setPrice(double newPrice)throws Exception{
    if(newPrice >= 0){
        this.price = newPrice;
    }
    else{
        CDException cde = new CDException();
        cde.setMessage("CD Price cannot be negative,\nCannot create CD");
        throw cde;
    }
}

so my question is...

is there a way to do this in one step, check both that the user entered a number and that the number is non negative. one other thing is that if the input is blank, that is the instruction to end the input loop.

Upvotes: 1

Views: 7502

Answers (3)

Eran Medan
Eran Medan

Reputation: 45775

I know this is for homework and this answer might not be accepted by your class instructor, but in the "real world" I would use a validation framework rather than reinvent the wheel, for example the built in one in Java EE 6: http://en.wikipedia.org/wiki/Bean_Validation

Here is a tutorial using them: http://docs.oracle.com/javaee/6/tutorial/doc/gircz.html

Some examples:

public class CD {
    @NotNull
    @Size(min=1, max=16)
    private String CDName;

    @Digits(integer=6, fraction=2)
    BigDecimal price;

}

Benefits

  • DRY (don't repeat yourself, e.g. declare validation once)
  • Readable (it's clear and documented)

Drawbacks

  • Java EE has some tendency for over complicating things, but it's still a valid choice
  • Not everyone likes the "Magic" of using annotations and like to see the code in their eyes

I'm sure there are more pros / cons, but that's out of the scope of this answer / question.

Upvotes: 2

Perception
Perception

Reputation: 80633

Having it split out into separate functions is better, in my opinion. You have better separation of concerns, which promotes code reuse. It's a pretty straightforward 'mashup' though, if you insist on combining the functions (which I don't think you should):

public void setPrice(String newPriceStr) throws CDException {
    if(newPriceStr == null) throw new CDException("Null value given for price");

    double newPrice = -1;

    try {
        newPrice = Double.valueOf(newPriceStr);
    } catch(final NumberFormatException nfe) {
        throw new CDException("Price must be a number,\nCannot create CD");
    }
    if(newPrice >= 0){
        this.price = newPrice;
    }
    else{
        throw new CDException("CD Price cannot be negative,\nCannot create CD");
    }
}

Note the shortened form for creating and throwing exceptions.

Upvotes: 2

Isaac
Isaac

Reputation: 16736

Well, you could change your code to read:

try {
    price = Double.parseDouble(strPrice);
    if (price < 0) {
        throw new CDException("Can't be negative");
    }
} catch (NumberFormatException ex) {
     ...
}

But the question is whether you'd really like to do that. From a design perspective, it might make more sense to do the "negative" check inside setPrice, rather than doing it as part of the parsing logic.

Upvotes: 2

Related Questions