0

I am not able to understand flow of control in the following code:

class Television {
    private int channel=setChannel(7);

    public Television (int channel) {
        this.channel=channel;
        System.out.println(channel + "");
    }

    public int setChannel(int channel) {
        this.channel=channel;
        System.out.print(channel + " ");
        return channel;
    }
}

public class TelevisionMain {
    public static void main(String[] args) {
        Television t = new Television(12);
    }
}

The output is 7 12.

It means explicit invocation occurs first. I am new to java and I thought that execution starts from main so the constructor should have been invoked first. Can anyone please explain why this happens.

Brian
  • 17,079
  • 6
  • 43
  • 66
roshan
  • 2,410
  • 2
  • 25
  • 37
  • 4
    It does. You're creating an instance of the Television class, which then proceeds to immediately initialize the local channel integer by calling the specified method. It then executes the code in the constructor. – Surveon Nov 01 '13 at 20:04
  • 2
    Because [that's what the Java Language Spec says must happen.](http://stackoverflow.com/a/14806340/139010) Why do you think that the constructor _must_ happen before default initialization? – Matt Ball Nov 01 '13 at 20:04
  • To behave otherwise would be madness, if it happened the other way round you could never overwrite a default value – Richard Tingle Nov 01 '13 at 20:06

4 Answers4

2

initialisation is part of construction and it is defined to occur after the super() has been called and before the body of the constructor.

the constructor should have been invoked first.

It is. The field initialisation is part of the constructor.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

Your Television constructor is compiled to roughly:

public Television(int channel)
{
    super();
    this.channel = this.setChannel(7);
    this.channel = channel;
    System.out.println(channel+"");
}

So when you call Television t = new Television(12);, it first sets the channel to 7, then 12.

Tim S.
  • 55,448
  • 7
  • 96
  • 122
  • The first set to the channel variable is actually done in a static block. It would not be compiled into the existing constructor. – keaplogik Nov 03 '13 at 21:53
  • 1
    @keaplogik it didn't appear so when I looked at it with the javap disassembler: it showed just two blocks of code: the constructor and the `setChannel` method. – Tim S. Nov 04 '13 at 00:32
0

Ultimately the answer is because the specification says it should. However it is reasonable that it be this way round because to behave the otherway round would make it impossible to overwrite a default initialed value

If the order were constructor first then everything else, then the order would be

  • called Television(12)
  • channel set to 12 within constructor
  • channel set back to 7 by int channel=setChannel(7);

This is clearly an unreasonable state of affairs as you could never use default values because these default values could not be changed by a constructor

Richard Tingle
  • 16,906
  • 5
  • 52
  • 77
0

In Java there is essentially a hidden default constructor. If you don't declare one, you can initialize a variable at the top of a class with a default variable. That's the way we like to think of it anyways. The reality is that each class has a static block where variables can be declared and played with before actual constructor declaration hits during the class load process.

I feel like your above declaration is similar to this, and that is why you are seeing the output 7 12.

class Television {
   //The below code is essentially equal to your declaration of
   // private int channel = setChannel(7);
   private int channel;
   static{
       //This occurs before constructor call during class load.
       channel = setChannel(7);
   }
   ....
}

A better explanation can be found in the java tutorials on Initializing Fields

keaplogik
  • 2,369
  • 2
  • 25
  • 26