1

I want to throw an exception in order to let the user know that the age value input should be between 1 and 120. Find below the example.

Is there a better way to throw an exception?

public class Lesson18Encapsulation3 {

    private int age;
    private String name;
    private int salary;

    public int getAge() {
        return age;
    }
    public void setAge(int age) {

        if ( age < 0 && age >= 120) 

            this.age = age;
        throw new IllegalArgumentException (" age can not be negative or more than 120");

//getters and setters

    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
public class Lesson18Encapsulation4 {

    public static void main(String[] args) {
        Lesson18Encapsulation3 emp = new Lesson18Encapsulation3();

        emp.setAge(220);
        emp.setName("None");

        System.out.println( "age : " + emp.getAge());
        System.out.println( "name : " + emp.getName());
    }
}
3
  • 1
    Note that if the age is not valid, you shouldn't do this.age = age;. You may also consider using Java Validation Api, an example here : baeldung.com/javax-validation Commented Sep 25, 2018 at 8:03
  • 1
    Are you sure about the if clause for the age? I doubt there are people with age of -8. :) Commented Sep 25, 2018 at 9:03
  • This is just to protect Data from misuse. Someone can change the age via setter method. Lesson18Encapsulation3 emp = new Lesson18Encapsulation3(); emp.setAge(220); // Error: Throw new IllegalArgumentException emp.setAge(-8); // Erro: Throw new IllegalArgumentException Commented Sep 25, 2018 at 15:09

2 Answers 2

4

In principle, what you are doing here is an instance of design by contract: You are defining a pre-condition for your method.

A) Wrong Condition

Your condition is wrong. You want to throw the exception in exactly the opposite case:

if(age < 0 || age >= 120) {
   // Throw exception
}

(This was also pointed out by @Nikolas in an earlier post)

B) Make Design by Contract Explicit

I'd make this explicit by providing an Assertion-method:

private void setAge(int age) {
    assertCorrectAge(age);
    this.age = age;
}

private void assertCorrectAge(int age) {
    if(age < 0 || age >= 120) {
        throw new IllegalArgumentException(" ... ");
    }
}

Some people will suggest to use Java's build in assert keyword. I suggest to not do that, because it is disabled in most JVM versions (so it doesn't fire).

C) Use a library

Having many assertion method for checking pre-conditions, adds up to a lot of boilerplate code. You could have a library take care of this (for example Google's Guava):

public void setAge(int age) {
    Preconditions.checkArgument(age >= 0, "negative age: %s", age);
    Preconditions.checkArgument(age < 120, "age too high: %s", age);
    this.age = age;
}
Sign up to request clarification or add additional context in comments.

4 Comments

A brings nothing new. B is not necessary - much better would be a use of Java Validation API. Agreed that avoiding the assert keyword is a good way. C I recommend again the Java Validation API rather than Guava.
Thanks for the comment. I disagree particularly regarding B: It is an improvement towards readibility and makes the intent clearer. Also, it encapsulates the check of the pre-condition. Regarding A: I was not aware that you had pointed out this as well. I apologize and will edit my post to reflect your contribution.
Well A brings the correct if-clause (which I assume is wrong in the question). C is a suggestion. I thought Java Validation API could be a little bit too much.
Your comment on C makes me think a bit more: It might be true for a Java EE context. But in general Java, I have not seen it used for the checks of invariants, pre- and post conditions. Can you provide an example application/ reference?
2

The condition is wrong. You want to set the age only if the range is between 0 and 120:

if (age >= 0 && age < 120) {
    this.age = age;
} else throw new IllegalArgumentException("Age can not be negative or more than 120");

Alternatively (note the changed || operator which means or):

if (age < 0 || age >= 120) {
    throw new IllegalArgumentException("Age can not be negative or more than 120");  
}
this.age = age;

Throwing an exception itself upon wrong input is perfectly valid.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.