A static method called from a constructor in Java

The question is about Java static methods.

Animal() 
{ 
    this(makeRandomName());          
}

      

I have this code in Java Animal a = new Animal()

makeRandomName

that gets called when I create an object for animals: - a method that returns a string obtained randomly from an array of String values ​​using Math.random()

. If I don't specify the makeRandomName method as static , I get this error (you can explain why):

Exception on thread "main" java.lang.RuntimeException: Uncompilable source code - cannot reference this until the supertype constructor is called

Also, when the Animal constructor is defined like this:

Animal() 
{
    this.name = makeRandomName();           
}

      

I don't get any errors no matter if makeRandomName is static or non-static. What for? What is the difference between this.name = makeRandomName();

andthis(makeRandomName());

I've never seen this syntax this(method_name())

before, I've only seen it this.instance_variable = value

, so I'm a little confused. I'm sure it has to do with super constructors and the order of the methods called, but it would be great to see the expert analysis of the methods and constructors in this case and the order of the method calls. Thank you very much in advance!

I was prompted to post all the code:

public class Animal {
    String name;
    Animal (String n)
    {
        this.name = n;
    }
    Animal() 
    {

        this(makeRandomName());
        //this.name=makeRandomName();

    }
    static String makeRandomName()
    {
        int x = (int) (Math.random()*5);
        String l[] = new String[] {"Zlatan", "Ibra", "Edinson", "Gigi", "T"};
        return l[x];

    }
    public static void main(String [] args)
    {
        Animal a = new Animal();
        Animal b = new Animal("M");
        System.out.println(a.name);
        System.out.println(b.name);
    }
}

      

+3


source to share


4 answers


For the first question - the reason makeRandomName()

must be specified as static, since it makeRandomName()

is an instance method and will not be available until it is called in the constructor super

, which forces the class initialzed. What you are trying to do is call makeRandomName()

before the call super

initializes the class, which will result in a compilation error.

In the second question, there is an implicit call super();

before your status this.name = makeRandomName();

. super(...);

should always be the first statement in a constructor, even if you don't explicitly write it. Hence the actual code for your second constructor is:



Animal() {
    super();
    this.name = makeRandomName();
}

      

makeRandomName()

is available at this point, even if it is declared non-static, because the object has already been constructed.

+8


source


In the first case, this()

you are trying to call the constructor of a class, and you are trying to pass the results of a method defined in that class to it. The object you created in the beginning was not initialized at this point, so it tries to access a method from within itself that has not yet been initialized. super()

must be called before you can access that method, but in that case you cannot call super()

, then this()

because java requires to this()

be the first statement in your constructor if you put it there.

this(makeRandomName())

calls the constructor and tries to pass the result makeRandomName()

to the constructor call. The problem is that the object has not been initialized at this point, so makeRandomName()

it cannot be called.



this.name = makeRandomName()

assigns return to a makeRandomName()

class instance variable after object initialization

It doesn't make sense to call a constructor inside a constructor because you will have a recursive situation ... Unless there is some constructive reason for this, but in that case, you need a base case to break the recursion at some point.

+1


source


You see this problem because you call the object (vs Class): "makeRandomName" method before running the superclass constructor (you pass the results as a parameter). Before any method can be run on an object, the super object's constructor must be executed. Therefore, always always the first line of the constructor

+1


source


You called your instance method

makeRandomName () before super()

, it is not available as no instance / object has been created yet.

The following constuctor works because the constructor itself is called super()

by default in the first line

constructor bodies.

Animal() {
        //this(makeRandomName());
        this.name=makeRandomName();
}

      

Your next constructor that you called will not be called in your constructor this()

in this case , but unfortunately not available.super()

Animal()

Animal(String name)

makeRandomName()

Animal() {
   this(makeRandomName()); 
   //this.name=makeRandomName();
}


Animal(String name){
    // super() is invoked implicitly here...
}

      

+1


source







All Articles