Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - How to only create an object with valid attributes?

I'm doing a basic Java course and I came to a problem: How do I create an object only if I have passed valid parameters to the Constructor?

Should I make an alternate class and call the constructor from there after the validation is realized?

Or should/could I use a static method in the class for the validation?

What is the best practice in this case?

like image 794
Tiago Duque Avatar asked Jun 12 '15 12:06

Tiago Duque


People also ask

How do you set values to objects in Java?

The set() method of java. lang. reflect. Field is used to set the value of the field represented by this Field object on the specified object argument to the specified new value passed as parameter.

Can an attribute be an object in Java?

Attributes are an object's data, and methods are an object's code.

How can you avoid creating an object of a class?

You can often avoid creating unnecessary objects by using static factory methods (Item 1) in preference to constructors on immutable classes that provide both. For example, the static factory method Boolean. valueOf(String) is almost always preferable to the constructor Boolean(String).


1 Answers

The standard practice is to validate the arguments in the constructor. For example:

class Range {
  private final int low, high;
  Range(int low, int high) {
    if (low > high) throw new IllegalArgumentException("low can't be greater than high");
    this.low = low;
    this.high = high;
  }
}

Side note: to verify that arguments are not null, which is fairly common, you can use:

import static java.util.Objects.requireNonNull;

Constructor(Object o) {
  this.o = requireNonNull(o); //throws a NullPointerException if 'o' is null
}

UPDATE

To reply to your specific comment about social security number. One way would be to add a method to the class:

//constructor
public YourClass(String ssn) {
  if (!isValidSSN(ssn)) throw new IllegalArgumentException("not a valid SSN: " + ssn);
  this.ssn = ssn;
}

public static boolean isValidSSN(String ssn) {
  //do some validation logic
}

The calling code could then look like:

String ssn = getSsnFromUser();
while(!YourClass.isValidSSN(ssn)) {
  showErrorMessage("Not a valid ssn: " + ssn);
  ssn = getSsnFromUser();
}
//at this point, the SSN is valid:
YourClass yc = new YourClass(ssn);

With that design, you have achieved two things:

  • you validate the user input before using it (which you should always do - users are very good at typos)
  • you have made sure that if YourClass is misused an exception is thrown and it will help you detect bugs

You could go further by creating a SSN class that holds the SSN and encapsulates the validation logic. YourClass would then accept a SSN object as an argument which is always a valid SSN by construction.

like image 161
assylias Avatar answered Oct 08 '22 05:10

assylias