Java method call in constructor chaining - java

Is it possible to call a constructor with the result of a method from another constructor of the same class?
I want to be able to accept input in several forms, and have something like:
public class MyClass
{
public MyClass(int intInput)
{
...
}
public MyClass(String stringInput);
{
this(convertToInt(stringInput));
}
public int convertToInt(String aString)
{
return anInt;
}
}
When I try to compile this, I get
error: cannot reference this before supertype constructor has been called
refering to convertToInt.

You just need to make convertToInt static. Since it doesn't really rely on on anything in the class instance, it probably doesn't really belong on this class anyway.
Here's an example:
class MyClass {
public MyClass(String string) {
this(ComplicatedTypeConverter.fromString(string));
}
public MyClass(ComplicatedType myType) {
this.myType = myType;
}
}
class ComplicatedTypeConverter {
public static ComplicatedType fromString(String string) {
return something;
}
}
You have to do it this way because, behind the scenes, the super-constructor (in this case Object) needs to be called before your own constructor is run. By referring to this (via the method call) before that invisible call to super(); happens you're violating a language constraint.
See the JLS section 8.8.7 and more of the JLS section 12.5.

The method convertToInt can't be called, because it needs to be run by an object, not just from a class. Therefore, changing the code to
public static int convertToInt(String aString)
{
return anInt;
}
means that convertToInt before the constructor has finished.

No its not possible. To call instance method all your super class constructor must have been called. In this case you are calling this() which replaces call to super(). You can not have both super() and this() in the same function either. So super class instance is not initialized in your case hence you are getting this error.
You can call like this
public MyClass(String stringInput) {
super(); // No need to even call... added just for clarification
int i = convertToInt(stringInput);
}
Making the method static might solve your problem.

Related

Calling a function from a constructor

How can I have the Edit() method be called by default when I construct a Breuk object?
public class Breuk {
public Breuk() {//constructor
}
private static Breuk Edit (Breuk b){ //function
}
}
Every time a new Breuk object is created, the Edit() method is called by default since it is placed inside the constructor. As the method is static, it has to be called in a statically way, i.e. ClassName.staticMethod(). As the method expects a Breuk object as argument, you pass this reference to it, meaning the object that's being constructed.
By the way, all method names should be lowercase according to Java conventions. So, consider renaming Edit(...) to edit(...).
class Breuk {
int x;
int y;
public Breuk(int x, int y) {
Breuk.Edit(this);
}
private static void Edit(Breuk b){
//edits breuk
}
}
First of all, you should stick to Java naming conventions, which state that method names should be lowerCamelCase. So you should rename your Edit() method to edit().
If you want the edit() method to be called by default when constructing an instance of the Breuk class, you can use an initializer block.
Excerpt from the Java Tutorial:
The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.
For your example, you could try something like this:
public class Breuk {
{ // initializer block
Breuk.edit(this); // always called by default,
// no matter which constructor is used
}
public Breuk() { // no-args constructor
}
public Breuk(int a1, int a2) { // another constructor
}
private static Breuk edit(Breuk b) { // function
}
}
Here I'm assuming you want to pass the instance being constructed to the edit() method, that's why this is passed as an argument.
EDIT:
In case this assumption is true, I suggest you make the edit() method return void, as you can't assign an instance to this, since it's final (and it doesn't make any sense, either).
Just call the method from the end of your default constructor. There's no need to think about any "default" calling here. Just implement it.
public class Breuk {
public Breuk() {
// constructor
edit(this);
}
private static Breuk edit (Breuk b){
// class-level processing on any Breuk that is constructed
}
}

why use super when constructing a subclass [duplicate]

Java requires that if you call this() or super() in a constructor, it must be the first statement. Why?
For example:
public class MyClass {
public MyClass(int x) {}
}
public class MySubClass extends MyClass {
public MySubClass(int a, int b) {
int c = a + b;
super(c); // COMPILE ERROR
}
}
The Sun compiler says, call to super must be first statement in constructor. The Eclipse compiler says, Constructor call must be the first statement in a constructor.
However, you can get around this by re-arranging the code a little bit:
public class MySubClass extends MyClass {
public MySubClass(int a, int b) {
super(a + b); // OK
}
}
Here is another example:
public class MyClass {
public MyClass(List list) {}
}
public class MySubClassA extends MyClass {
public MySubClassA(Object item) {
// Create a list that contains the item, and pass the list to super
List list = new ArrayList();
list.add(item);
super(list); // COMPILE ERROR
}
}
public class MySubClassB extends MyClass {
public MySubClassB(Object item) {
// Create a list that contains the item, and pass the list to super
super(Arrays.asList(new Object[] { item })); // OK
}
}
So, it is not stopping you from executing logic before the call to super(). It is just stopping you from executing logic that you can't fit into a single expression.
There are similar rules for calling this(). The compiler says, call to this must be first statement in constructor.
Why does the compiler have these restrictions? Can you give a code example where, if the compiler did not have this restriction, something bad would happen?
The parent class' constructor needs to be called before the subclass' constructor. This will ensure that if you call any methods on the parent class in your constructor, the parent class has already been set up correctly.
What you are trying to do, pass args to the super constructor is perfectly legal, you just need to construct those args inline as you are doing, or pass them in to your constructor and then pass them to super:
public MySubClassB extends MyClass {
public MySubClassB(Object[] myArray) {
super(myArray);
}
}
If the compiler did not enforce this you could do this:
public MySubClassB extends MyClass {
public MySubClassB(Object[] myArray) {
someMethodOnSuper(); //ERROR super not yet constructed
super(myArray);
}
}
In cases where a parent class has a default constructor the call to super is inserted for you automatically by the compiler. Since every class in Java inherits from Object, objects constructor must be called somehow and it must be executed first. The automatic insertion of super() by the compiler allows this. Enforcing super to appear first, enforces that constructor bodies are executed in the correct order which would be: Object -> Parent -> Child -> ChildOfChild -> SoOnSoForth
I've found a way around this by chaining constructors and static methods. What I wanted to do looked something like this:
public class Foo extends Baz {
private final Bar myBar;
public Foo(String arg1, String arg2) {
// ...
// ... Some other stuff needed to construct a 'Bar'...
// ...
final Bar b = new Bar(arg1, arg2);
super(b.baz()):
myBar = b;
}
}
So basically construct an object based on constructor parameters, store the object in a member, and also pass the result of a method on that object into super's constructor. Making the member final was also reasonably important as the nature of the class is that it's immutable. Note that as it happens, constructing Bar actually takes a few intermediate objects, so it's not reducible to a one-liner in my actual use case.
I ended up making it work something like this:
public class Foo extends Baz {
private final Bar myBar;
private static Bar makeBar(String arg1, String arg2) {
// My more complicated setup routine to actually make 'Bar' goes here...
return new Bar(arg1, arg2);
}
public Foo(String arg1, String arg2) {
this(makeBar(arg1, arg2));
}
private Foo(Bar bar) {
super(bar.baz());
myBar = bar;
}
}
Legal code, and it accomplishes the task of executing multiple statements before calling the super constructor.
Because the JLS says so. Could the JLS be changed in a compatible manner to allow it? Yup.
However, it would complicate the language spec, which is already more than complicated enough. It wouldn't be a highly useful thing to do and there are ways around it (call another constructor with the result of a static method or lambda expression this(fn()) - the method is called before the other constructor, and hence also the super constructor). So the power to weight ratio of doing the change is unfavourable.
Note that this rule alone does not prevent use of fields before the super class has completed construction.
Consider these illegal examples.
super(this.x = 5);
super(this.fn());
super(fn());
super(x);
super(this instanceof SubClass);
// this.getClass() would be /really/ useful sometimes.
This example is legal, but "wrong".
class MyBase {
MyBase() {
fn();
}
abstract void fn();
}
class MyDerived extends MyBase {
void fn() {
// ???
}
}
In the above example, if MyDerived.fn required arguments from the MyDerived constructor they would need to be sleazed through with a ThreadLocal. ;(
Incidentally, since Java 1.4, the synthetic field that contains the outer this is assigned before inner classes super constructor is called. This caused peculiar NullPointerException events in code compiled to target earlier versions.
Note also, in the presence of unsafe publication, construction can be viewed reordered by other threads, unless precautions are made.
Edit March 2018: In message Records: construction and validation Oracle is suggesting this restriction be removed (but unlike C#, this will be definitely unassigned (DU) before constructor chaining).
Historically, this() or super() must be first in a constructor. This
restriction was never popular, and perceived as arbitrary. There were
a number of subtle reasons, including the verification of
invokespecial, that contributed to this restriction. Over the years,
we've addressed these at the VM level, to the point where it becomes
practical to consider lifting this restriction, not just for records,
but for all constructors.
Simply because this is the inheritance philosophy. And according to the Java language specification, this is how the constructor's body is defined:
ConstructorBody:
{ ExplicitConstructorInvocationopt BlockStatementsopt }
The first statement of a constructor body may be either
an explicit invocation of another constructor of the same class (by using the keyword "this"); or
an explicit invocation of the direct superclass (by using the keyword "super")
If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments. And so on.. there will be a whole chain of constructors called all the way back to the constructor of Object; "All Classes in the Java platform are Descendants of Object". This thing is called "Constructor Chaining".
Now why is this?
And the reason why Java defined the ConstructorBody in this way, is that they needed to maintain the hierarchy of the object. Remember the definition of the inheritance; It's extending a class. With that being said, you cannot extend something that doesn't exist. The base (the superclass) needs to be created first, then you can derive it (the subclass). That's why they called them Parent and Child classes; you can't have a child without a parent.
On a technical level, a subclass inherits all the members (fields, methods, nested classes) from its parent. And since Constructors are NOT members (They don't belong to objects. They are responsible of creating objects) so they are NOT inherited by subclasses, but they can be invoked. And since at the time of object creation only ONE constructor is executed. So how do we guarantee the creation of the superclass when you create the subclass object? Thus the concept of "constructor chaining"; so we have the ability to invoke other constructors (i.e. super) from within the current constructor. And Java required this invocation to be the FIRST line in the subclass constructor to maintain the hierarchy and guarantee it. They assume that if you don't explicitly create the parent object FIRST (like if you forgot about it), they will do it implicitly for you.
This check is done during compilation. But I'm not sure what would happen on runtime, what kind of runtime error we would get, IF Java doesn't throw a compile-error when we explicitly try to execute a base constructor from within a subclass's constructor in the middle of its body and not from the very first line ...
I am fairly sure (those familiar with the Java Specification chime in) that it is to prevent you from (a) being allowed to use a partially-constructed object, and (b), forcing the parent class's constructor to construct on a "fresh" object.
Some examples of a "bad" thing would be:
class Thing
{
final int x;
Thing(int x) { this.x = x; }
}
class Bad1 extends Thing
{
final int z;
Bad1(int x, int y)
{
this.z = this.x + this.y; // WHOOPS! x hasn't been set yet
super(x);
}
}
class Bad2 extends Thing
{
final int y;
Bad2(int x, int y)
{
this.x = 33;
this.y = y;
super(x); // WHOOPS! x is supposed to be final
}
}
You asked why, and the other answers, imo, don't really say why it's ok to call your super's constructor, but only if it's the very first line. The reason is that you're not really calling the constructor. In C++, the equivalent syntax is
MySubClass: MyClass {
public:
MySubClass(int a, int b): MyClass(a+b)
{
}
};
When you see the initializer clause on its own like that, before the open brace, you know it's special. It runs before any of the rest of the constructor runs and in fact before any of the member variables are initialized. It's not that different for Java. There's a way to get some code (other constructors) to run before the constructor really starts, before any members of the subclass are initialized. And that way is to put the "call" (eg super) on the very first line. (In a way, that super or this is kind of before the first open brace, even though you type it after, because it will be executed before you get to the point that everything is fully constructed.) Any other code after the open brace (like int c = a + b;) makes the compiler say "oh, ok, no other constructors, we can initialize everything then." So it runs off and initializes your super class and your members and whatnot and then starts executing the code after the open brace.
If, a few lines later, it meets some code saying "oh yeah when you're constructing this object, here are the parameters I want you to pass along to the constructor for the base class", it's too late and it doesn't make any sense. So you get a compiler error.
So, it is not stopping you from executing logic before the call to
super. It is just stopping you from executing logic that you can't fit
into a single expression.
Actually you can execute logic with several expessions, you just have to wrap your code in a static function and call it in the super statement.
Using your example:
public class MySubClassC extends MyClass {
public MySubClassC(Object item) {
// Create a list that contains the item, and pass the list to super
super(createList(item)); // OK
}
private static List createList(item) {
List list = new ArrayList();
list.add(item);
return list;
}
}
I totally agree, the restrictions are too strong. Using a static helper method (as Tom Hawtin - tackline suggested) or shoving all "pre-super() computations" into a single expression in the parameter is not always possible, e.g.:
class Sup {
public Sup(final int x_) {
//cheap constructor
}
public Sup(final Sup sup_) {
//expensive copy constructor
}
}
class Sub extends Sup {
private int x;
public Sub(final Sub aSub) {
/* for aSub with aSub.x == 0,
* the expensive copy constructor is unnecessary:
*/
/* if (aSub.x == 0) {
* super(0);
* } else {
* super(aSub);
* }
* above gives error since if-construct before super() is not allowed.
*/
/* super((aSub.x == 0) ? 0 : aSub);
* above gives error since the ?-operator's type is Object
*/
super(aSub); // much slower :(
// further initialization of aSub
}
}
Using an "object not yet constructed" exception, as Carson Myers suggested, would help, but checking this during each object construction would slow down execution. I would favor a Java compiler that makes a better differentiation (instead of inconsequently forbidding an if-statement but allowing the ?-operator within the parameter), even if this complicates the language spec.
I found a woraround.
This won't compile :
public class MySubClass extends MyClass {
public MySubClass(int a, int b) {
int c = a + b;
super(c); // COMPILE ERROR
doSomething(c);
doSomething2(a);
doSomething3(b);
}
}
This works :
public class MySubClass extends MyClass {
public MySubClass(int a, int b) {
this(a + b);
doSomething2(a);
doSomething3(b);
}
private MySubClass(int c) {
super(c);
doSomething(c);
}
}
My guess is they did this to make life easier for people writing tools that process Java code, and to some lesser degree also people who are reading Java code.
If you allow the super() or this() call to move around, there are more variations to check for. For example if you move the super() or this() call into a conditional if() it might have to be smart enough to insert an implicit super() into the else. It might need to know how to report an error if you call super() twice, or use super() and this() together. It might need to disallow method calls on the receiver until super() or this() is called and figuring out when that is becomes complicated.
Making everyone do this extra work probably seemed like a greater cost than benefit.
Can you give a code example where, if the compiler did not have this restriction, something bad would happen?
class Good {
int essential1;
int essential2;
Good(int n) {
if (n > 100)
throw new IllegalArgumentException("n is too large!");
essential1 = 1 / n;
essential2 = n + 2;
}
}
class Bad extends Good {
Bad(int n) {
try {
super(n);
} catch (Exception e) {
// Exception is ignored
}
}
public static void main(String[] args) {
Bad b = new Bad(0);
// b = new Bad(101);
System.out.println(b.essential1 + b.essential2);
}
}
An exception during construction almost always indicates that the object being constructed could not be properly initialized, now is in a bad state, unusable, and must be garbage collected. However, a constructor of a subclass has got the ability to ignore an exception occurred in one of its superclasses and to return a partially initialized object. In the above example, if the argument given to new Bad() is either 0 or greater than 100, then neither essential1 nor essential2 are properly initialized.
You may say that ignoring exceptions is always a bad idea. OK, here's another example:
class Bad extends Good {
Bad(int n) {
for (int i = 0; i < n; i++)
super(i);
}
}
Funny, isn't it? How many objects are we creating in this example? One? Two? Or maybe nothing...
Allowing to call super() or this() in the middle of a constructor would open a Pandora's box of heinous constructors.
On the other hand, I understand a frequent need to include some static part before a call to super() or this(). This might be any code not relying on this reference (which, in fact, already exists at the very beginning of a constructor, but cannot be used orderly until super() or this() returns) and needed to make such call. In addition, like in any method, there's a chance that some local variables created before the call to super() or this() will be needed after it.
In such cases, you have the following opportunities:
Use the pattern presented at this answer, which allows to circumvent the restriction.
Wait for the Java team to allow pre-super() and pre-this() code. It may be done by imposing a restriction on where super() or this() may occur in a constructor. Actually, even today's compiler is able to distinguish good and bad (or potentially bad) cases with the degree enough to securely allow static code addition at the beginning of a constructor. Indeed, assume that super() and this() return this reference and, in turn, your constructor has
return this;
at the end. As well as the compiler rejects the code
public int get() {
int x;
for (int i = 0; i < 10; i++)
x = i;
return x;
}
public int get(int y) {
int x;
if (y > 0)
x = y;
return x;
}
public int get(boolean b) {
int x;
try {
x = 1;
} catch (Exception e) {
}
return x;
}
with the error "variable x might not have been initialized", it could do so on this variable, making its checks on it just like on any other local variable. The only difference is this cannot be assigned by any means other than super() or this() call (and, as usual, if there is no such call at a constructor, super() is implicitly inserted by compiler in the beginning) and might not be assigned twice. In case of any doubt (like in the first get(), where x is actually always assigned), the compiler could return an error. That would be better than simply return error on any constructor where there is something except a comment before super() or this().
You can use anonymous initializer blocks to initialize fields in the child before calling it's constructor. This example will demonstrate :
public class Test {
public static void main(String[] args) {
new Child();
}
}
class Parent {
public Parent() {
System.out.println("In parent");
}
}
class Child extends Parent {
{
System.out.println("In initializer");
}
public Child() {
super();
System.out.println("In child");
}
}
This will output :
In parent
In initializer
In child
It makes sense that constructors complete their execution in order of
derivation. Because a superclass has no knowledge of any subclass, any
initialization it needs to perform is separate from and possibly
prerequisite to any initialization performed by the subclass.
Therefore, it must complete its execution first.
A simple demonstration:
class A {
A() {
System.out.println("Inside A's constructor.");
}
}
class B extends A {
B() {
System.out.println("Inside B's constructor.");
}
}
class C extends B {
C() {
System.out.println("Inside C's constructor.");
}
}
class CallingCons {
public static void main(String args[]) {
C c = new C();
}
}
The output from this program is:
Inside A's constructor
Inside B's constructor
Inside C's constructor
I know I am a little late to the party, but I've used this trick a couple of times (and I know it's a bit unusual):
I create an generic interface InfoRunnable<T> with one method:
public T run(Object... args);
And if I need to do something before passing it to the constructor I just do this:
super(new InfoRunnable<ThingToPass>() {
public ThingToPass run(Object... args) {
/* do your things here */
}
}.run(/* args here */));
Actually, super() is the first statement of a constructor because to make sure its superclass is fully-formed before the subclass being constructed. Even if you don't have super() in your first statement, the compiler will add it for you!
That's because your constructor depends on other constructors. To your constructor work correctly its necessary to other constructor works correctly which is dependent. That's why its necessary to check dependent constructors first which called by either this() or super() in your constructor. If other constructors which called by either this() or super() have a problem so whats point execute other statements because all will fail if called constructor fails.
The question of why Java does this has already been answered, but since I stumbled upon this question hoping to find a better alternative to the one-liner, I'll hereby share my work-around:
public class SomethingComplicated extends SomethingComplicatedParent {
private interface Lambda<T> {
public T run();
}
public SomethingComplicated(Settings settings) {
super(((Lambda<Settings>) () -> {
// My modification code,
settings.setting1 = settings.setting2;
return settings;
}).run());
}
}
Calling a static function should perform better, but I would use this if I insist on having the code "inside" the constructor, or if I have to alter multiple parameters and find defining many static methods bad for readability.
This is official replay:
Historically, this() or super() must be first in a constructor. This
restriction was never popular, and perceived as arbitrary. There were a
number of subtle reasons, including the verification of invokespecial,
that contributed to this restriction. Over the years, we've addressed
these at the VM level, to the point where it becomes practical to
consider lifting this restriction, not just for records, but for all
constructors.
Tldr:
The other answers have tackled the "why" of the question. I'll provide a hack around this limitation:
The basic idea is to hijack the super statement with your embedded statements. This can be done by disguising your statements as expressions.
Tsdr:
Consider we want to do Statement1() to Statement9() before we call super():
public class Child extends Parent {
public Child(T1 _1, T2 _2, T3 _3) {
Statement_1();
Statement_2();
Statement_3(); // and etc...
Statement_9();
super(_1, _2, _3); // compiler rejects because this is not the first line
}
}
The compiler will of course reject our code. So instead, we can do this:
// This compiles fine:
public class Child extends Parent {
public Child(T1 _1, T2 _2, T3 _3) {
super(F(_1), _2, _3);
}
public static T1 F(T1 _1) {
Statement_1();
Statement_2();
Statement_3(); // and etc...
Statement_9();
return _1;
}
}
The only limitation is that the parent class must have a constructor which takes in at least one argument so that we can sneak in our statement as an expression.
Here is a more elaborate example:
public class Child extends Parent {
public Child(int i, String s, T1 t1) {
i = i * 10 - 123;
if (s.length() > i) {
s = "This is substr s: " + s.substring(0, 5);
} else {
s = "Asdfg";
}
t1.Set(i);
T2 t2 = t1.Get();
t2.F();
Object obj = Static_Class.A_Static_Method(i, s, t1);
super(obj, i, "some argument", s, t1, t2); // compiler rejects because this is not the first line
}
}
Reworked into:
// This compiles fine:
public class Child extends Parent {
public Child(int i, String s, T1 t1) {
super(Arg1(i, s, t1), Arg2(i), "some argument", Arg4(i, s), t1, Arg6(i, t1));
}
private static Object Arg1(int i, String s, T1 t1) {
i = Arg2(i);
s = Arg4(s);
return Static_Class.A_Static_Method(i, s, t1);
}
private static int Arg2(int i) {
i = i * 10 - 123;
return i;
}
private static String Arg4(int i, String s) {
i = Arg2(i);
if (s.length() > i) {
s = "This is sub s: " + s.substring(0, 5);
} else {
s = "Asdfg";
}
return s;
}
private static T2 Arg6(int i, T1 t1) {
i = Arg2(i);
t1.Set(i);
T2 t2 = t1.Get();
t2.F();
return t2;
}
}
In fact, compilers could have automated this process for us. They'd just chosen not to.
Before you can construct child object your parent object has to be created.
As you know when you write class like this:
public MyClass {
public MyClass(String someArg) {
System.out.println(someArg);
}
}
it turns to the next (extend and super are just hidden):
public MyClass extends Object{
public MyClass(String someArg) {
super();
System.out.println(someArg);
}
}
First we create an Object and then extend this object to MyClass. We can not create MyClass before the Object.
The simple rule is that parent's constructor has to be called before child constructor.
But we know that classes can have more that one constructor. Java allow us to choose a constructor which will be called (either it will be super() or super(yourArgs...)).
So, when you write super(yourArgs...) you redefine constructor which will be called to create a parent object. You can't execute other methods before super() because the object doesn't exist yet (but after super() an object will be created and you will be able to do anything you want).
So why then we cannot execute this() after any method?
As you know this() is the constructor of the current class. Also we can have different number of constructors in our class and call them like this() or this(yourArgs...). As I said every constructor has hidden method super(). When we write our custom super(yourArgs...) we remove super() with super(yourArgs...). Also when we define this() or this(yourArgs...) we also remove our super() in current constructor because if super() were with this() in the same method, it would create more then one parent object.
That is why the same rules imposed for this() method. It just retransmits parent object creation to another child constructor and that constructor calls super() constructor for parent creation.
So, the code will be like this in fact:
public MyClass extends Object{
public MyClass(int a) {
super();
System.out.println(a);
}
public MyClass(int a, int b) {
this(a);
System.out.println(b);
}
}
As others say you can execute code like this:
this(a+b);
also you can execute code like this:
public MyClass(int a, SomeObject someObject) {
this(someObject.add(a+5));
}
But you can't execute code like this because your method doesn't exists yet:
public MyClass extends Object{
public MyClass(int a) {
}
public MyClass(int a, int b) {
this(add(a, b));
}
public int add(int a, int b){
return a+b;
}
}
Also you are obliged to have super() constructor in your chain of this() methods. You can't have an object creation like this:
public MyClass{
public MyClass(int a) {
this(a, 5);
}
public MyClass(int a, int b) {
this(a);
}
}
class C
{
int y,z;
C()
{
y=10;
}
C(int x)
{
C();
z=x+y;
System.out.println(z);
}
}
class A
{
public static void main(String a[])
{
new C(10);
}
}
See the example if we are calling the constructor C(int x) then value of z is depend on y if we do not call C() in the first line then it will be the problem for z. z would not be able to get correct value.
The main goal of adding the super() in the sub-class constructors is that the main job of the compiler is to make a direct or indirect connection of all the classes with the Object class that's why the compiler checks if we have provided the super(parameterized) then compiler doesn't take any responsibility.
so that all the instance member gets initialized from Object to the sub - classes.

PMD Overridable method called during object construction

I have the following structure
public class parent {
int value ;
}
public class child extends parent {
int childValue;
public child(){}
public child (int value){
this.childValue = value ; // this line cause ConstructorCallsOverridableMethod warning during object construction
}
}
Could you please advice how to solve this error ?
The PMD rule says:
Calling overridable methods during construction poses a risk of invoking methods on an incompletely constructed object and can be difficult to debug. It may leave the sub-class unable to construct its superclass or forced to replicate the construction process completely within itself, losing the ability to call super(). If the default constructor contains a call to an overridable method, the subclass may be completely uninstantiable. Note that this includes method calls throughout the control flow graph - i.e., if a constructor Foo() calls a private method bar() that calls a public method buz(), this denotes a problem.
Example:
public class SeniorClass {
public SeniorClass(){
toString(); //may throw NullPointerException if overridden
}
public String toString(){
return "IAmSeniorClass";
}
}
public class JuniorClass extends SeniorClass {
private String name;
public JuniorClass(){
super(); //Automatic call leads to NullPointerException
name = "JuniorClass";
}
public String toString(){
return name.toUpperCase();
}
}
Solution
Delete any call to overridable methods in the constructor or add the final modifier to that methods.
Perhaps you could follow follow Java's Naming Conventions and also make the Child class final
public final class Child extends Parent {

Can I call a method before a constructor

I know I can call static methods inside a constructor.
I have one contructor in one class which is calling another constructor through this(arguments).
Secondly that second constructor is calling super(arguments) calling super constructor.
I want to execute some code before these constructors execute. I cannot use a static block. Any ideas?
You can call static methods. I often do it like this:
public class MyClass extends SuperDuperClass {
public MyClass() {
this(convert("Foo!")); // convert will be executed
// other constructor is called
}
public MyClass(String arg) {
super(convert(arg)); // convert will be executed
// before superconstructor is called
}
private static String convert(String arg) {
return arg + "_modified";
}
}
Of course, we can't call instance methods or use non static fields.
(and, of course, this pattern requires a constructor on super that takes parameters)
The super() call has to be the first statement in a constructor, no exceptions apart from statics which you've already mentioned you can't use.
Even when you don't explicitly write a super() call at the start of your constructor, the compiler puts it in for you. It's always there!
Your best bet is to refactor your code so you don't feel the need to call anything before the super() call, but without seeing the code (or at least more context behind it) no-one can tell you how is best to do that!
You can't - the first thing java needs is a super.constructer call - written or not!
Use the factory pattern so you can do this:
public static MyObject newInstance() {
staticMethod();
return new MyObject();
}
Assuming the static method isn't supposed to actually change how the constructor behaves, that will literally call it before the constructor is executed.
You can do this, also without a static block:
public Main() {
System.out.println("Inside Constructor");
}
{
System.out.println("Before Constructor");
}
public void doTest() {
this.doTest();
}

Java passing subclass instance data to superclass constructors

Does anybody know if there's a way in Java to set the value of an instance variable in a subclass before calling the superclass constructor. I have a brief schematic below of what I'm trying to accomplish -- I need to set up the instance variables defined in the superclass differently depending on the subclass type, but I still want to be able to share common non-constructor code among different instances of the subclass.
Is there any clean way to do this, maybe some sort of coding pattern that I'm missing or something? Thanks in advance for any ideas.
public abstract class ConstraintSatisfactionProblem {
final Set<Variable> variables;
final Set<Constraint> constraints;
public Foo() {
this.variables = setupVariables();
this.constraints = setupConstraints();
}
public abstract Set<Variable> setupVariables();
public abstract Set<Constraint> setupConstraints();
public Map<Variable, Constraint> solve() { ... }
}
public class WordSquare extends ConstraintSatisfactionProblem {
final int size;
final static Set<Character> domain = ...;
public WordSquare() {
super(); // can I simulate calling super() after setting this.value = 4?
this.value = 4;
}
public Set<Variable> setupVariables() {
this.variables = new HashSet<Variable>();
for(int row = 0; row < size; ++row) {
for(int col = 0; col < size; ++col) {
variables.add(new Variable<Pair, Character>(new Pair(row, col), domain);
}
}
return this.variables;
}
public Set<Constraint> setupConstraints() {
// setup code specific to this problem
}
}
public class Cryptarithmetic extends ConstraintSatisfactionProblem {
final String problem;
public Cryptarithmetic(String problem) {
super();
this.problem = problem;
}
public Set<Variable> setupVariables() {
this.variables = new HashSet<Variable>();
for(char c : problem.toCharArray()) {
variables.add(new Variable<Character, Integer>(c, getDomain());
}
}
return this.variables;
}
public Set<Constraint> setupConstraints() {
// setup code specific to this problem
}
}
Firstly, please don't.
Secondly, really it's a really bad idea. Don't. Think about what you are trying to do in a broader context.
If you absolutely must do, you can stash it in a ThreadLocal. You can call a (non-instance) method by evaluating an expression the result of which is passed to a super() or this() (possibly the only reason why you need a second, private constructor that possibly takes a Void (capital 'V') argument). It's so evil, I am not going to even write the code down.
In your edited example code, just pass the sets into a protected constructor. If you have many arguments possibly some subclasses being special about some arguments, you might want to wrap all the arguments into a single argument object.
There is another really hacky approach, so long as you have -target 1.4 or later (which you should do!). Make the subclass an inner class (possibly anonymous). The references to the outer this and other captured variables are available before calling the super constructor.
public class Outer {
// What a hack!
private static abstract class Base {
Base() {
hello(); // Calling a virtual method in a constructor - poor form.
}
abstract void hello();
}
public static void main(String[] args) {
// Do not do this.
final String hi = "Hi!";
new Base() {
void hello() {
// Really, don't do it.
System.err.println(hi);
}
};
}
}
Place the common code you want to run in a protected method instead of in the constructor. Call that method when you wish.
You should never call any "alien" method (ie. overridable method of this class, or any method from any other class) form within a constructor. As long as the object is not fully initialized, you may have side-effects like the one you see.
In your case, in the subclass constructor, super() is called even before the "value" is set to 4. This means, the superclass constructor is called, then calls the "setup" method, while the "value" is still at 0.
Only once the superclass constructor returns, the "value" is set to 4. And it's too late then.
What I would recommend, is to set the "o1" variable to protected, so that subclasses can set its value themselves.
In Java, if you want to call a base class's constructor, you have to do it on the first line of your sub-class's constructor. So the answer is no, you can't set this.value before calling the super class's constructor.
But your sub-class's setup() method is already called in the super's constructor. Why don't you set your value there?
UPDATE:
Sorry, I didn't pay attention that your 'setup()' method returns a value. What you could do is make an abstract init() method in your super class, and call it in your super constructor before you call the setup() method. This way sub-classes will be forced to implement init(), and you would know that that is the place to initialize any sub-class's members before they are used in your super-class.
That being said, this approach does not force safety on you. When you call the super constructor from your sub-constructor, the sub-class instance is just starting to get created. It still needs to run the rest of the code in the sub-constructor before the object is safely created.
And in this situation, the super-constructor goes and calls the init() method on your just-in-the-process-of-creation sub-class. This means that if you go with approach, you have to be extra careful about what you do in the init() class.
Like others have said, don't do this. If you want to share some code between these classes, try containment/encapsulation instead of inheritance.
public class Foo {
private final Object o1;
public Foo(Object o) {
o1 = o;
}
public void complexMethodCommonToAllSubclassesOfFoo() { ... }
}
public class Bar {
private final int value;
private final Foo foo;
public Bar() {
super();
this.value = 4;
this.foo = new Foo( new Object() ); // or whatever
}
// If you need to expose complexMethodCommonToAllSubclassesOfFoo to clients of this class, just add the method and delegate to foo like this
public void complexMethodCommonToAllSubclassesOfFoo() {
foo.complexMethodCommonToAllSubclassesOfFoo();
}
}
I need to set up the instance variables defined in the superclass differently depending on the subclass type, but I still want to be able to share common non-constructor code among different instances of the subclass.
In that case, create a protected constructor in the superclass, and pass all of the customized values to it when you construct the subclass.

Categories