One option is to use a factory method, which lets you do something and then have the constructor run:
public class subClass extends mySuperClass {
private subClass(int y) { // <-- Note: Now private
super(/* ... args ... */);
this.y = y;
}
public static subClass create(int y) {
if (y >= 10) {
throw new IllegalArgumentException("Shame! Shame!");
}
return new subClass(y);
}
}
Now, you'd create objects by writing subClass.create(arg);
rather than new subClass(arg);
A second option would be to replace the int
parameter with a parameter of a custom type representing what you want. This gives more fine-grained control and makes clear that the argument isn't an int
per se, but rather some sort of limited value.
public class subClass extends mySuperClass {
public static final class SpecialInt {
private final int value;
SpecialInt(int val) {
if (val < 10) {
throw new IllegalArgumentException("That int is Not Special.");
}
value = val;
}
}
public subClass(SpecialInt y) {
super(/* ... args ... */);
this.y = y.value;
}
}
I like this option because it makes clear that there's a restricted type of items that can be given to the constructor, though it does add a bit more syntax (new subClass(new subClass.SpecialInt(137))
versus newSubclass(137)
).
A final, hacky, "not great but it'll work" option would be to add in static method that checks the argument to the subclass constructor and, in the normal case, returns the proper argument to the superclass constructor. However, if the argument is invalid, the helper throws an exception. This assumes that the superclass constructor takes at least one argument and won't work otherwise.
public class subClass extends mySuperClass {
private static final String argCheck(int y) {
if (y >= 10) {
throw new IllegalArgumentException("You have committed a Programming Sin.");
}
return /* whatever you would normally send to the superclass. */;
}
public subClass(int y) {
super(argCheck(y)); // Check y before invoking the superclass ctor
this.y = y;
}
}