This discussion is archived
8 Replies Latest reply: Apr 3, 2013 4:26 PM by 9423755 RSS

What's happening here?

9423755 Explorer
Currently Being Moderated
Hi

I'm just starting out (again) on learning java and below is the first of a set of sample certification questions on oracle's website (reformatted for clarity):
public class Sequence { 
    Sequence() { 
                    System.out.print("c "); 
    } 
    { 
        System.out.print("y "); 
    } 
    public static void main(String[] args) { 
        new Sequence().go(); 
    } 
    void go() { 
        System.out.print("g "); 
    } 
    static { 
            System.out.print("x "); 
    } 
} 
I've managed to compile it (yay!) using just the command line rather than the JDeveloper sledgehammer (doubly yay!) but with my foggy prior knowledge of java, am confused.
My understanding is that "new Sequence().go()" will cause the constructor to fire in order to create an instance of Sequence so that the member function "go()" can fire. So why then does this create the following output:
x y c g
So yes, I would have expected "c g". What do you call the block that outputs "y", why is it firing, and why is the static function that outputs "x" firing?

Many thanks,
Jason
  • 1. Re: What's happening here?
    Kayaman Guru
    Currently Being Moderated
    Jason_942375 wrote:
    What do you call the block that outputs "y", why is it firing,
    It's a (non-static) initialization block, which is run when an instance is created, i.e. at the same time as a constructor.
    and why is the static function that outputs "x" firing?
    It's not a function, it's a static initialization block that is run when the class is loaded.
  • 2. Re: What's happening here?
    9423755 Explorer
    Currently Being Moderated
    Thanks. That would make sense.

    So, the order is:

    1. class is loaded --> runs a static initialization block if present
    2. main() function runs, which calls Sequence().go() which causes three things to happen:
    3.a class instance initialization block runs
    3.b class instance constructor function runs
    3.c member function go() runs

    Is that correct?

    Interesting. FWIW I just changed the code to
        public static void main(String[] args) { 
            new Sequence().go(); 
            new Sequence().go(); 
        } 
    and got
    x y c g y c g
    showing that the static (i.e. class level) initialization block is only run once (but that the non-static initialization block runs for each new instance of the class). What action or events would or could cause it (the class level initialization block that here outputs "x") to run twice? Would you have to do something like "unload" the class from the JVM?

    Many thanks,
    Jason
  • 3. Re: What's happening here?
    gimbal2 Guru
    Currently Being Moderated
    Is that correct?
    No need to be unsure dude, your output backs it up. You're right on the money. When you're a little further ahead I would suggest you learn to use either Netbeans or Eclipse and learn to use their debuggers, then you can really see what the execution flow of your application is by stepping through it line by line.

    As for static initializers - the class would have to be loaded again, in a different classloader or indeed reloaded in the same classloader (which is only really possible since Java 7). Classloaders are an advanced topic, I wouldn't worry about that just yet. I can also say that static initializers are more an exception than a rule, you won't use them often.
  • 4. Re: What's happening here?
    9423755 Explorer
    Currently Being Moderated
    Ok great, many thanks :-)
  • 5. Re: What's happening here?
    rp0428 Guru
    Currently Being Moderated
    >
    What action or events would or could cause it (the class level initialization block that here outputs "x") to run twice? Would you have to do something like "unload" the class from the JVM?
    >
    If you want all of the details you should save and read the Java Language Specification.
    http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.7
    >
    A static initializer declared in a class is executed when the class is initialized (§12.4.2). Together with any field initializers for class variables (§8.3.2), static initializers may be used to initialize the class variables of the class.
    >
    Review this bullet of the referenced section 12.4.2: 12.4.2. Detailed Initialization Procedure
    >
    Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.
  • 6. Re: What's happening here?
    EJP Guru
    Currently Being Moderated
    1. class is loaded --> runs a static initialization block if present
    2. main() function runs, which calls Sequence().go() which causes three things to happen:
    3.a class instance initialization block runs
    3.b class instance constructor function runs
    3.c member function go() runs

    Is that correct?
    No.

    1. Class is loaded.
    2. Static init block runs.
    3. main() runs.
    4. Constructor starts.
    5. Constructor calls super().
    6. Instance init blocks and variable declarations with initializers run.
    7. Code after super() call in constructor runs.
    8. go() runs.
    What action or events would or could cause it (the class level initialization block that here outputs "x") to run twice?
    None short of reloading the class.
  • 7. Re: What's happening here?
    9423755 Explorer
    Currently Being Moderated
    >
    1. Class is loaded.
    2. Static init block runs.
    3. main() runs.
    4. Constructor starts.
    5. Constructor calls super().
    6. Instance init blocks and variable declarations with initializers run.
    7. Code after super() call in constructor runs.
    8. go() runs.
    >

    Ok, thanks for the clarification. Looking at it, it seems the difference between what I understood and what you say happens is that if the class has a parent class (which I suppose must always be so) then the parent's constructor runs before the current class's instance initialzation block.
  • 8. Re: What's happening here?
    EJP Guru
    Currently Being Moderated
    the parent's constructor runs before the current class's instance initialzation block.
    Blocks, and that includes variable declarations with initializers.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points