3

My questions is this:

Why can I not pass this to an explicit call to a constructor?

Example:

class MyClass {

    MyClass x;

    public MyClass(MyClass c) {
        x = c;
    }

    public MyClass() {
        this(this);        // Error
    }
}
Lii
  • 11,553
  • 8
  • 64
  • 88
kafka
  • 949
  • 12
  • 27

3 Answers3

4

You are trying to pass a reference to this from a constructor to another constructor on the same instance.

In Java you cannot access this implicitly or explicitly in the constructor before returning from an implicit or explicit call to this() or super(). This is because the super class has not yet initialised.

You may need to duplicate code in the constructor:

class MyClass {
    private final MyClass myInstance;
    public MyClass(MyClass myInstance) {
        this.myInstance = myInstance;
    }
    public MyClass() {
        this.myInstance = this;
    }
}

There may be ways to hack around it using a private constructor, but then you are into hacking territory.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
0

Below is a work around to this restriction.

The work around is to pass a temporary holder object to the super class constructor. Then after the super class constructor has done its work, give the temporary holder object a reference to this.

The parameter delta can be used to show the principal shortcoming of this workaround - what if the superclass constructor needs to use the parameter.

import java . lang . reflect . * ;
import java . util . * ;

class Father
{
    public static void main ( String [ ] args )
    {
         ( new Son ( args . length > 0 ) ) . run ( ) ;
    }

    Father ( Runnable runnable , boolean delta )
    {
         super ( ) ;
         if ( delta )
         {
        runnable . run ( ) ;
         }
    }
}

class Son extends Father implements Runnable
{
    private static Map < Thread , TempRunnable > temps = new HashMap < Thread , TempRunnable > ( ) ;

    private static class TempRunnable implements Runnable
    {
         private Son son ;

         TempRunnable ( )
         {
             super ( ) ;
             temps . put ( Thread . currentThread ( ) , this ) ;
         }

         public void run ( )
         {
             son . run ( ) ;
         }
    }

    Son ( boolean delta )
    {
         // super ( this ) ; // the dream
         super ( new TempRunnable ( ) , delta ) ;
         temps . get ( Thread . currentThread ( ) ) . son = this ;
    }

    public void run ( )
    {
         System . out . println ( "Hello World" ) ;
    }
}
emory
  • 10,725
  • 2
  • 30
  • 58
0

As workaround, You could assign this to x as the default value when you pass null to the constructor.

class MyClass {
    
   final MyClass x;
   
   public MyClass(MyClass c){
       x = c == null ? this : c;
   }

   public MyClass(){
       this(null);
   }

}
Max S
  • 152
  • 1
  • 9