I thought the result could be '43' because the type of q was 'poly 1'. However, the result was '44'. I couldn't understand that. please give me the answer.
class poly1 {
int a;
public poly1(){
a = 3;
}
public void print_a(){
System.out.print(a);
}
}
public class poly2 extends poly1{
public poly2(){
a = 4;
}
public void print_a(){
System.out.print(a);
}
public static void main(String[] args){
poly2 p = new poly2();
p.print_a();
poly1 q = new poly2();
q.print_a();
}
}
When you invoke a class' constructor, the class' super type constructor is invoke first (until there is no super types).
When you invoke
new poly2();
The poly1 constructor is invoked first (because poly1 is a super type of poly2), setting a to 3 and then the poly2 constructor is invoked, setting a to 4 which is what you see.
the type of q was 'poly 1'
What seems to confuse you is that in the following code
poly1 q = new poly2();
the variable q is declared as type poly1. That makes no difference in this case. What actually matters is the run time type of the object. That's determined by the new statement. In this case, the object is of dynamic type poly2.
When you run this program,at
poly2 p = new poly2();
a's value is 4 as it initialised by the constructor of poly2, again at
poly1 q = new poly2();
a's value is initalised by the constructor of poly2 to 4,so it will print 4 again giving a output of "44".
Everytime u instatiate "p" and "q" ,the value of "a" is first initialised by the constructor of poly1 and again the calue of "a" gets initialised by constructor of class poly2 as poly2 extends poly1 class.
Try debugging the code and you will get to know the exact flow of the program.
According to the language specs, instance variables aren't even initialized until a super() call has been made.
These are the steps performed during the constructor step of class instance creation/
Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.
If this constructor begins with an explicit constructor invocation (§8.8.7.1) of another constructor in the same class (using this), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5.
This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.
Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5.
Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally.
Sorry about my earlier answer.. Apparently, I hadn't seen the question correctly...
public static void main(String[] args){
poly2 p = new poly2();
p.print_a();
poly1 q = new poly2();
q.print_a();
}
Now, when you do :
poly2 p = new poly2();
The following happens..
poly2 constructor is called.
poly2 constructor forwards the creation call to poly1 constructor.
The value of a is 3 (initialized in poly1 constructor)
The control comes back to poly2 constructor
a is set to 4 in poly2 constructor.
The same thing happens in the second case as well.
they are all realize of Poly2, so they use the structure function of Poly2, so console display"44"
When you run this program,at the below line
poly2 p = new poly2();
a's value is 4 as it initialised by the constructor of poly2, again at the below line
poly1 q = new poly2();
the refrence you are creating is of poly1 but at runtime the object is created of poly2 so at this line a's value becomes 4 that's why you are getting the result 44.
Methods are invoked by looking at object. In your case the object is of class Poly2 so in both the case it will invoke Poly2 class's print_a method.
Addition
Execution of constructor matters here. sequence of execution of constructor is first base class constructor and then derived class constructor.
Related
I have this simple piece of code.
abstract class X {
X() {
read();
}
private void read() {
Object obj = new Object();
readValue(obj);
}
protected abstract void readValue(Object obj);
}
class Y extends X {
Object obj = null;
Y() {
super();
}
#Override
protected void readValue(Object obj) {
this.obj = obj;
}
void printer() {
System.out.println("Object = " + obj);
}
}
class Runner {
public static void main(String[] args) {
Y y = new Y();
y.printer();
}
}
When I run the above code, the object gets printed as null. (I get "Object = null")
Surprisingly, in class Y when I remove null declaration
Object obj;
The actual value of the object is printed.
Something like ("Object = java.lang.Object#3cd1a2f1")
Why is such a behavior observed? What is 'this' pointing to? Any object is initialized by null if we just declare it, then why such an aberrant behavior?
The reason the obj field is null is due to the sequence of steps that occur in the constructor call of Y:
The constructor of Y calls the super constructor which eventually calls readValue of the concrete class Y, therefore assigning a non-null value to the obj field.
After the super constructor finishes, the instance field obj is initialized to null due to the variable initializer:
Object obj = null;
When you remove the null initializer, it becomes a simple field declaration with no instance initialization to be performed in step 2.
The apt solution is not to remove the null initializer, but to re-design the whole class hierarchy. For example, since the purpose of readValue seems to just be a setter for a variable, then you don't need to make it override an abstract method in the parent class. Just set it as a separate method and call it after the constructor of Y completes.
This illustrates the dangers of calling an inherited method in a subclass from a superclass constructor. The main danger is that initializers for variables in a subclass run after the superclass constructor completes.
Here is what happens.
An object of y is created.
The superclass constructor X() is called, which calls read().
The read method creates a new Object and passes it to readValue, which is implemented in Y.
The readValue method in Y sets obj to the new object.
The superclass constructor X() completes, and initializers run now in Y, setting obj to null.
The printer method prints "Object = null".
If you remove the declaration of obj in Y, then there is no initializer to run, and the obj variable retains its value.
The JLS, Section 12.5, states:
[A]ll the instance variables in the new object, including those declared in superclasses, are initialized to their default values (§4.12.5).
Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:
Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.
If this constructor begins with an explicit constructor invocation (§8.8.7.1) of another constructor in the same class (using this), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5.
This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.
Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5.
Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally.
(emphasis mine)
and
Unlike C++, the Java programming language does not specify altered rules for method dispatch during the creation of a new class instance. If methods are invoked that are overridden in subclasses in the object being initialized, then these overriding methods are used, even before the new object is completely initialized.
The object is null because The superclass constructor runs before the subclass constructor,hence it would only be natural that the statement Object obj = null; is executed after calling super class constructor.
The assignment of Object obj = null; is inlined into the constructor during compile time. This are only accessible in existing instance,
and instance does not exist yet when you are in constructor (it is still under construction).
You can achieve object value(Object = java.lang.Object#3cd1a2f1) by declaringobject object as static.
static Object obj = null;
Generally though, it's bad practice to call overriden methods from a constructor in real time.
I have just started learning Java.I understand
Unlike instance method, instance variable can not be overridden, and are not dynamically picked by JVM at run time when accessed polymorphically.
flow of execution : static block, super constructor, initialization block and then constructor.
But I am stuck at one code, where I have polymorphically invoked a instance variable but its showing overridden value (which it should not show). The instance variable is overridden inside sub class' init block.
package package1;
public class Other {
public static void main(String [] args){
Parent referToChild = new Child();
Parent referToChildTwo = new ChildTwo();
System.out.println("age as referred by referToChild reference variable is:" + referToChild.age);// prints 35 (doubt 1)
System.out.println("age as referred by referToChildTwo reference variable is:" + referToChildTwo.age);// prints 50 (doubt 2)
System.out.println("money as referred by Other reference variable is:" + referToChild.money);
//System.out.println("Other reference variable is:" + othObj.age);
}
}
class Child extends Parent{
// init block
{
age = 35;
}
}
class ChildTwo extends Parent{
public int age;
{
age = 40;
}
}
class Parent{
public int age = 50;
public int money = 100;
}
The answer I get is:
35
50
100
so my doubts are:
doubt 1 :Why is it showing "35", it should display super class' variable's value which is 50.
doubt 2 : When it is displaying sub class' variable's value for last case, then why not for this case.
Why is it showing "35", it should display super class' variable's value which is 50.
The initializer block of subclass Child executes after the variable age is initialized in the Parent class. Therefore, age is first initialized to 50, then to 35.
This is explained in great detail in the Java Language Specification Section 12.5 on Creation of New Class Instances, with the relevant part in bold:
Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:
Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.
If this constructor begins with an explicit constructor invocation (§8.8.7.1) of another constructor in the same class (using this), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5.
This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.
Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5.
Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally.
As for the second question, referToChildTwo is declared of type Parent, while its actual type is ChildTwo. A ChildTwo instance has two age fields, the one defined in ChildTwo and the other one inherited from Parent.
When you write the expression referToChildTwo.age, the field inherited in Parent will be evaluated. To evaluate the one defined in the subclass, you would need to cast the variable, i.e. ((ChildTwo)referToChildTwo).age.
It cannot be overridden, but it is inherited by child classes as long as it wasn't private in the parent. And they can access it, including both reading and writing it.
Overriding is creating a new member which is part of the current class, which has the same definition of the member of the parent class, and for that member to be accessed when you use the object polymorphically.
For example:
class Parent {
public int age = 50;
}
class Child {
public int age = 80;
}
Here we defined a new member, age, which is separate from the parent's age. If you access it from inside Child using this.age, you'll get 80. If you access the parent's age using super.age, you'll get 50.
But this is not overriding, because if you use the object polymorphically, it will access the parent's age:
Child childObj = new Child();
Parent parentObj = childObj;
System.out.println( childObj.age ); // Will print 80
System.out.println( parentObj.age ); // Will print 50
This is despite the fact that they are both the same object. That's because the child hides the field rather than override it.
Simply assigning a value in a field inherited from the parent is not overriding. It's part of what inheritance is all about.
There is a code which is given as a task for a junior Java developers. I use Java during five years and this piece of code completely confusing me:
public class Main {
String variable;
public static void main(String[] args) {
System.out.println("Hello World!");
B b = new B();
}
public Main(){
printVariable();
}
protected void printVariable(){
variable = "variable is initialized in Main Class";
}
}
public class B extends Main {
String variable = null;
public B(){
System.out.println("variable value = " + variable);
}
protected void printVariable(){
variable = "variable is initialized in B Class";
}
}
The output will be:
Hello World!
variable value = null
But if we change String variable = null; to String variable; we will have:
Hello World!
variable value = variable is initialized in B Class
The second output is more clear for me.
So, as far as I know the sequence of inizialisation in Java like this:
We go to the root of the class hierarchy (for Java it is always Object class), when we come to this root parent class:
All static data fields are initialized;
All static field initializers and static initialization blocks are executed;
All non-static data fields are initialized;
All non-static field initializers and non-static initialization blocks are executed;
The default constructor is executed;
Then we repeat the procedure for the underlying child class.
Also there is post which describes the behavior of the this keyword in context of a superclass - Calling base class overridden function from base class method
Based on the rules given above, I assume to have sequence like this:
We are going to create a new instance of class B;
We go to the part class Main;
Initialize main.variable with null;
Then we move to the default constructor of class Main;
Constructor calls method b.printVariable() in class Main; (Why doesn't it call main.printvariable? We don't have this key word here.)
The field b.variable "variable is initialized in B Class"
Now we come back to the class B;
We should initialize field b.variable with null value, am I right?;
The default constructor of class B executed
Please, can someone give a complete and full explanation of how this inheritance inizialisation sequence works. And why changing String variable = null; to String variable; leads to another output.
The sequence is:
Main -> "Hello"
Main -> new B()
B() -> Main() -> b.printVariable() -> sets the variable
Back to initialising B, so variable=null occurs.
So basically, the super object Main() is constructed before any intialisation events of class B. Which means variable=null occurs later. This makes sense as otherwise B could break the initialisation of Main.
Joshua Bloch covers a lot of good ground in his effective java book about how dangerous inheritance is to get right, I would recommend it.
First, you need to understand, what happens when you write variable = null;. When is that code executed. This basically determines the output.
Before I begin, I should also mention that when you create an object of class B, the printVariable() function of the main class is not called. Instead, always the printVariable() of B will be called.
Keeping this in mind, when you have variable = null, the execution for B's constructor will begin. First Main() will be called, which will call the printVariable() method. At last, variable=null, will be called overwriting the variable variable.
In the other case, where you do not initialize variable=null, the variable set by the printVariable() function will not be overwritten, hence you get what you were expecting.
In summary, this is the order of execution of statements, when you do new B():
Main() //super constructor
B#printVariable()
initializtion of variables in B's constructor (if any) [i.e. variable=null, if present]
This is a nice exercise! But it's not a fair question to ask junior developers. This one is for seniors. But to make this text useful during the technical interview, I'd modified it by adding an argument to the Main's constructor:
public Main(String something){
printVariable();
}
If the person will answer what will happen, then remove the argument and ask the original questions. If the person won't answer - there is no need to continue - s/he is junior.
You can also remove the protected qualifier in class B and ask what will happen if you have a goal not to hire this person :)
I have a few cases I wonder about. First, if you have no constructor:
class NoCons { int x; }
When I do new NoCons(), the default constructor gets called. What does it do exactly? Does it set x to 0, or does that happen elsewhere?
What if I have this situation:
class NoCons2 extends NoCons { int y; }
What happens when I call new NoCons2()? Does NoCons's default constructor get called, and then NoCons2's constructor? Do they each set the respective x and y fields to 0?
What about this version:
class Cons2 extends NoCons { int y; public Cons2() {} }
Now I have a constructor, but it doesn't call the super class's constructor. How does x ever get initialized? What if I had this situation:
class Cons { int x; public Cons() {} }
class NoCons2 extends Cons { int y; }
Will the Cons constructor be called?
I could just try all these examples, but I can't tell when a default constructor is run. What's a general way to think about this so that I'll know what happens in future situations?
When a Java class has no constructor explicitly defined a public no-args default constructor is added so:
class Cons { int x; }
is equivalent to:
class Cons { int x; public Cons() {} }
A subclass's constructor that doesn't explicitly define which of its parent's constructor it calls will automatically call the default constructor in the parent class before it does anything else. So assuming:
class A { public A() { System.out.println("A"); } }
then this:
class B extends A { public B() { System.out.println("B"); } }
is exactly equivalent to:
class B extends A { public B() { super(); System.out.println("B"); } }
and the output in both cases will be:
A
B
So when you do:
new NoCons2();
The order is:
NoCons's default constructor called, although this is technically the first part of (2); and then
NoCons2's default constructor called.
You want to refer to the Java Language Specification section 12.5 Creation of New Class Instances to get the official rules of object creation. The relevant section is:
Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:
Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.
If this constructor begins with an explicit constructor invocation of another constructor in the same class (using this), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5.
This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.
Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5. (In some early implementations, the compiler incorrectly omitted the code to initialize a field if the field initializer expression was a constant expression whose value was equal to the default initialization value for its type.)
Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally.
So in your examples, when no constructor is supplied in your class definition, the default one is inserted for you. When you write
new NoCons2();
First the super constructor is called (a call to super() is inserted for you because you don't make the call explicitly).
Instance variables for the class being constructed are initialized.
The rest of the constructor body is executed (nothing in your case).
In your first example, x will be set during the construction of NoCons and y will be set during the construction of NoCons2.
So the exact sequence of events in that example will be something like:
NoCons2 constructor called.
Call to super(), goto 3
NoCons constructor called.
Call to super(), which is an implicit call to Object().
Whatever happens in Object constructor.
x is set to 0.
finish body of NoCons constructor, return control back to NoCons2 constructor.
y is set to 0.
finish body of NoCons2 constructor
NoCons2 object construction complete.
cletus answered the biggest of the questions. The answer to the other is that member variables in Java are initialized to 0, null or false (depending on the type).
Here is essentially what happens when "new" is called:
the memory is allocated (enough to hold all of the data members of the class, and all of the parent classes, and some housekeeping information)
the allocated memory is set to zero (which means 0, 0.0, false, null depending in the type)
the constructor is called for the class that is after "new" is called.
more things happen (coming after the next part)
If you do not provide a constructor the compiler does the following:
creates a no-argument constructor
the created constructor has the same access as the class (so public or package)
super() is called.
So when the constructor of the class after the "new" is called the very first thing it does is call "super()" which calls the parent constructor. This happens all the way up to java.lang.Object.
Before the body of the constructor is run the VM does the following:
the instance variables that are assigned values are given them
then the instance initializer block, if present is run.
The following code shows all of this:
public class Main
{
private Main()
{
}
public static void main(final String[] args)
{
final Foo fooA;
final Foo fooB;
fooA = new Foo(7);
System.out.println("---------------------");
fooB = new Foo(42);
}
}
class Bar
{
protected int valueA = getValue("valueA", 1);
protected int valueB;
static
{
System.out.println("static block for Bar happens only one time");
}
{
System.out.println("instance block for Bar happens one time for each new Bar");
System.out.println("valueA = " + valueA);
System.out.println("valueB = " + valueB);
}
Bar()
{
super(); // compiler adds this - you would not type it in
System.out.println("running Bar()");
System.out.println("valueA = " + valueA);
System.out.println("valueB = " + valueB);
valueB = getValue("valueB", 2);
}
protected static int getValue(final String name, final int val)
{
System.out.println("setting " + name + " to " + val);
return (val);
}
}
class Foo
extends Bar
{
protected int valueC = getValue("valueC", 1);
protected int valueD;
static
{
System.out.println("static block for Foo happens only one time");
}
{
System.out.println("instance block for Foo happens one time for each new Foo");
System.out.println("valueC = " + valueC);
System.out.println("valueD = " + valueD);
}
Foo(final int val)
{
super(); // compiler adds this - you would not type it in
System.out.println("running Foo(int)");
System.out.println("valueC = " + valueC);
System.out.println("valueD = " + valueD);
valueD = getValue("valueD", val);
}
}
class test
{
test() {
System.out.println("Constructor");
}
{ System.out.println("Hai"); }
}
public class sample
{
public static void main(String [] a) {
test t = new test();
}
}
In the above code, why is "Hai" printed before the test() constructor is called?
The test() constructor in the test class is above the "Hai" statement and should be called first, right?
Let express with a more clear example:
public class Test {
static {
System.out.println("static initializer");
}
{
System.out.println("instance initializer");
}
public Test() {
System.out.println("constructor");
}
}
and test it as follows:
public class Main {
public static void main(String[] args) {
Test test1 = new Test();
Test test2 = new Test();
}
}
output:
static initializer
instance initializer
constructor
instance initializer
constructor
The static initializers are executed only once during runtime, specifically during loading of the class. The instance initializers are executed during every instantiation before the constructor.
You can have more than one of them and they will be executed in the order as they appear in the coding.
The major benefit of instance initializers is that they are executed regardless of which constructor you use. They applies on each of them so that you don't need to duplicate common initialization over all of them.
The major benefit of static initializers is that they are executed only once during class loading. A well known real world example is the JDBC driver. When you do
Class.forName("com.example.jdbc.Driver");
which only executes the static initializers, then any (decent) JDBC driver will register itself in the DriverManager as follows
static {
DriverManager.registerDriver(new com.example.jdbc.Driver());
}
this way the DriverManager can find the right JDBC driver during getConnection().
Yes. It's an instance initializer. It's run as soon as the class is instantiated.
In the above code why is that the statement given within the braces ((i.e) "Hai") is Printed before the constructor is executed.
Because this is the expected behavior as described in the section 12.5 Creation of New Class Instances of the Java Language Specification :)
Just before a reference to the newly
created object is returned as the
result, the indicated constructor is
processed to initialize the new object
using the following procedure:
Assign the arguments for the constructor to newly created parameter
variables for this constructor
invocation.
If this constructor begins with an explicit constructor invocation of
another constructor in the same class
(using this), then evaluate the
arguments and process that constructor
invocation recursively using these
same five steps. If that constructor
invocation completes abruptly, then
this procedure completes abruptly for
the same reason; otherwise, continue
with step 5.
This constructor does not begin with an explicit constructor
invocation of another constructor in
the same class (using this). If this
constructor is for a class other than
Object, then this constructor will
begin with an explicit or implicit
invocation of a superclass constructor
(using super). Evaluate the
arguments and process that superclass
constructor invocation recursively
using these same five steps. If that
constructor invocation completes
abruptly, then this procedure
completes abruptly for the same
reason. Otherwise, continue with step
4.
Execute the instance initializers and instance variable initializers for
this class, assigning the values of
instance variable initializers to the
corresponding instance variables, in
the left-to-right order in which they
appear textually in the source code
for the class. If execution of any of
these initializers results in an
exception, then no further
initializers are processed and this
procedure completes abruptly with that
same exception. Otherwise, continue
with step 5. (In some early
implementations, the compiler
incorrectly omitted the code to
initialize a field if the field
initializer expression was a constant
expression whose value was equal to
the default initialization value for
its type.)
Execute the rest of the body of this constructor. If that execution
completes abruptly, then this
procedure completes abruptly for the
same reason. Otherwise, this procedure
completes normally.
See section 8.6 Instance Initializers for more details on... instance initializers.
Braces immediately within a class introduces an instance initialiser (introduced in Java 1.1). They are treated much the same as code to assign fields written as part of the declaration. So the following are equivalent:
private final Thing x = new Thing();
and
private final Thing x;
{
x = new Thing();
}
The code is executed by constructors immediately after calling a super constructor. So, assuming no other initialisation, the code can be written equivalently as part of the constructor:
private final Thing x;
public MyCLass() {
super(); // Often implicit.
x = new Thing();
}
Braces in the same position preceded by the static keyword and static initialisers, executed once when a class is initialised, not on a per-instance basis.