Reputation: 49
I am trying to create a constructor for an object that inherits another object, but this constructor should also prevent the creation of the object on certain conditions.
I have this code:
class Foo
{
double x;
public Foo(double init_x)
{
x = init_x;
}
}
class Bar extends Foo
{
public Bar(double init_x)
{
if(init_x < 10)
{
throw new Exception();
}
super(init_x);
}
}
Here are the errors when the code is compiled with a main defined:
test2.java:13: error: constructor Foo in class Foo cannot be applied to given types;
{
^
required: double
found: no arguments
reason: actual and formal argument lists differ in length
test2.java:18: error: call to super must be first statement in constructor
super(init_x);
^
2 errors
My question is: why did I get the first error even though I clearly specified Bar(double init_x)
and also for the second part if the super call has to be the first statement then how do I address this problem?
Upvotes: 1
Views: 151
Reputation: 14015
I believe that throw exception in constructor is not good practice. Of cause, this is just my opinion, but I think, it will be better to make simple factory method:
class Bar extends Foo
{
//hide constructor
private Bar(init_x){
super(init_x);
}
//factory method
public static Bar createBar(double init_x)
{
if(init_x >= 10)
{
return new Bar(init_x);
}else{
//you can return null, instead of throwing exception
throw new Exception();
}
}
}
And when you need instance of bar:
public static void main(String [] args){
Bar bar = Bar.createBar(104.3);
...
}
Upvotes: 0
Reputation: 31269
You have two options:
You move the check until after the call to super
. It's still before the method completes, so the caller will not see the object constructed - it prevents the construction at least in the view of the caller:
class Bar extends Foo {
public Bar(double init_x) throws Exception {
super(init_x);
if (init_x < 10) {
throw new Exception();
}
}
}
You do the check in another method that returns the value if it is correct, but throws an exception if it is not correct:
class Bar extends Foo {
private static double checkInitX(double init_x) throws Exception {
if (init_x < 10) {
throw new Exception();
}
return init_x;
}
public Bar(double init_x) throws Exception {
super(checkInitX(init_x));
}
}
You are allowed to call as an expression within the call to super any method that's not an instance method on the object that you're constructing. A good place to put that method is as a static method in the class.
But usually, option 1 is the best. Unless there is a very good reason not to call the super with an out-of-range value (like, the super constructor is very slow, or it throws another, confusing, exception if the value is out of range), option 2 is not necessary. (In the two cases mentioned, you're better off refactoring the superclass constructor)
Upvotes: 2
Reputation: 13821
The answer is stated in the error message you get: error: call to super must be first statement in constructor
Upvotes: 0