This question already has answers here:
Calling method from constructor
(2 answers)
Closed 9 years ago.
class Alpha
{
String name = "Alpha";
Alpha()
{
print();
}
void print()
{
System.out.println("Alpha Constructor");
}
}
class Beta extends Alpha
{
int i = 5;
String name = "Beta";
public static void main(String[] args)
{
Alpha a = new Beta();
a.print();//Line1 executes Beta constructor
System.out.println(a.name);//Line 2 displays Alpha instance variable
}
void print()
{
System.out.println(i);
}
}
This program compiles successfully and displays the following output.
0
5
Alpha
Questions
a) I dont understand why Alpha's constructor did not get executed first.
I believe "super()" will be called implicitly by every child constructor first ...right ?.
b) If Beta's constructor is already executed then why "5" is printed ? (Second Line in Output)
The third line I kinda understand (i.e Alpha's own variable will be displayed because casting is not yet done on "a" instance variable)
You are committing two "felonies" here:
calling an overridable method from the constructor;
declaring an instance variable in the subclass with the same name as the one in the superclass.
Both idioms result in surprising behavior. Specifically, 1. results in Beta#print being called from the Alpha's constructor, which results in printing 0 because you are invoking print on an unititialized instance of Beta. And this happens precisely because the superconstructor runs before the subclass constructor.
In summary, calling an overridden method from the constructor results in an unwanted reversal of the order of execution: control is transferred from the superclass constructor into the subclass method.
As for your question about why 5 is printed: a.print(), unlike a.name, is a method invocation subject to dynamic dispatch. So regardless of a's declared type (which is Alpha), the Beta#print method is invoked (the same happens in Alpha's constructor, but before the i variable is initialized).
class Alpha
{
String name = "Alpha";
Alpha()
{
print();
This one here actually invokes Beta.print(), because it #Overrides Alpha.print(). Since base class constructors are called first, the Beta part has not yet been initialized here, thus it prints 0 since...
}
void print()
{
System.out.println("Alpha Constructor");
}
}
class Beta extends Alpha
{
int i = 5;
this line of code has not yet been executed. Initialization within the class body is executed after the super class constructor (super()) but before the constructor body of the same class.
String name = "Beta";
public static void main(String[] args)
{
Alpha a = new Beta();
a.print();//Line1 executes Beta constructor
Here, it will print 5, as initialization of Beta (a) is finished.
System.out.println(a.name);//Line 2 displays Alpha instance variable
}
And this is said method actually beeing called:
void print()
{
System.out.println(i);
}
}
Init/Invocation order:
Object.Object()
Alpha.<instance vars>
Alpha.<constructor body>
Beta.print() which overrides Alpha.print() (prints Beta.i, which is still 0 (default) )
Beta.<instance vars> (Here Beta.i will be initialized to 5)
Beta.<constructor body>
Beta.print() which overrides Alpha.print() (prints Beta.i, which finally is 5, since initialization is finished)
I dont understand why Alpha's constructor did not get executed first.
It did execute first. I don't know what made you think it didn't. Perhaps the output 0. That is because you invoked the overridden method in constructor, which will call the method print() in Beta class. Now, since at that point of time, the variable i hasn't been initialized yet, it will print 0. See this answer for more details. I've also written a blog post on this topic.
I believe "super()" will be called implicitly by every child constructor first ...right ?
Not always. When you chain the constructor of the same class using this(), super() won't be added. Else super class constructor will be chained.
If Beta's constructor is already executed then why "5" is printed ?
Why wouldn't it? Beta constructor will initialize i with 5. The initialization which you do at the point of declaration is moved to every constructor of your class by the compiler, after the super() or this() statement, whatever is there.
Alpha's constructor does get executed first. If you put System.out.println("Alpha Ctr"); in Alpha() method you will notice Alpha Ctr getting printed.
The fact is that you've overridden print() method in child class Beta. Therefore Beta#print() gets executed instead of Alpha#print().
If you change Beta#print() little bit this behavior will be more clear:
void print() {
System.out.println(name + ": " + i);
}
This will now print:
null: 0
Beta: 5
Alpha
Here it is prints null: 0 because variable name & i are uninitialized at the time of construction of parent class Alpha.
Related
In java, how is a child object constructed?
I just started inheritance and these few points are not very clear to me:
Does the child object depend only on the child class' constructor, or does it also depend on the parent's constructor? I need some details about that point.
Also, is super() always called by default in a child constructor?
Any other information regarding this topic is appreciated.
I don't think "A child object" is a good way to think about this.
You're making an object. Like all objects, it is an instance of some specific class, (After all, new SomeInterface() does not compile) and like (almost) all objects, it is made because some code someplace (doesn't have to be your code, of course) ran the java expression new SomeSpecificClass(args); somewhere.
We could say it is a 'child object' because SomeSpecificClass is a child class of some other class.
But that's rather useless. That means the only way to ever make a new 'non-child' object would be to write new Object(); - after all, all classes except java.lang.Object are a child class: If you write public class Foo {}, java will interpret that exactly the same as if you had written public class Foo extends java.lang.Object {}, after all.
So, barring useless* irrelevancies, all objects are child objects, and therefore as a term, 'child object', I'd not use that.
That also means that ALL object creation goes through this 'okay and in what order and how do the constructors work' song and dance routine.
How it works is probably most easily explained by desugaring it all. Javac (the compiler) injects things if you choose to omit them, because a lot of things that feel optional (such as a constructor, a super call, or an extend clause), at the class file / JVM level, aren't**.
Sugar #1 - extends clause
Already covered: if you have no extends clause on your class def, javac injects extends java.lang.Object for you.
Sugar #2 - no super call in constructor
A constructor must either call some specific super constructor on its very first line, or, it it must call some other constructor from the same class on its very first line (this(arg1, arg2);). If you don't, java will inject it for you:
public MyClass(String arg) { this.arg = arg; }
// is treated as:
public MyClass(String arg) {
super();
this.arg = arg;
}
Notably including a compiler error if your parent class has no zero-arg constructor available.
Sugar #3: No constructor
If you write a class that has no constructor, then java makes one for you:
public YourClass() {}
It will be public, it will have no args, and it will have no code on it. However, as per sugar #2 rule, this then gets expanded even further, to:
public YourClass() {super();}
Field inits and code blocks get rewritten to a single block.
The constructor isn't the only thing that runs when you make new objects. Imagine this code:
public class Example {
private final long now = System.currentTimeMillis();
}
This code works; you can compile it. You can make new instances of Example, and the now field will hold the time as it was when you invoked new Example(). So how does that work? That feels a lot like constructor code, no?
Well, this is how it works: Go through the source file top to bottom and find every non-static initializing code you can find:
public class Example {
int x = foo(); // all non-constant initial values count
{
x = 10;
// this bizarre constructor is legal java, and also
// counts as an initializer.
}
}
and then move all that over to the one and only initializer that classes get, in the order you saw them.
Ordering
So, via sugar rules we have reduced ALL classes to adhere to the following rules:
ALL classes have a parent class.
ALL classes have at least 1 constructor.
ALL constructors invoke either another constructor or a constructor from parent.
There is one 'initializer' code block.
Now the only question is, in what order are things executed?
The answer is crazy. Hold on to your hats.
This is the order:
First, set all fields to 0/false/null of the entire 'construct' (the construct involves every field from Child all the way down to Object, of course).
Start with the actual constructor invoked on Child. Run it directly, which means, start with the first line, which neccessarily is either a this() or a super() invocation.
Evaluate the entire line, notably, evaluate all expressions passed as arguments. Even if those are themselves invocations of other methods. But, javac will do some minor effort to try to prevent you from accessing your fields (because those are all uninitialized! I haven't mentioned initializers yet!!).
Yeah, really. This means this:
public class Example {
private final long x = System.currentTimeMillis();
public Example() {
super(x); // x will be .... 0
// how's that for 'final'?
}
}
This will either end up invoking the first line of some other constructor of yours (which is itself also either a this() or a super() call). Either we never get out of this forest and a stack overflow error aborts our attempt to create this object (because we have a loop of constructors that endlessly invoke each other), or, at some point, we run into a super() call, which means we now go to our parent class and repeat this entire song and dance routine once more.
We keep going, all the way to java.lang.Object, which by way of hardcoding, has no this() or super() call at all and is the only one that does.
Then, we stop first. Now the job is to run the rest of the code in the constructor of j.l.Object, but first, we run Object's initializer.
Then, object's constructor runs all the rest of the code in it.
Then, Parent's initializer is run. And then the rest of the parent constructor that was used. and if parent has been shifting sideways (this() invokes in its constructors), those are all run in reverse order as normal in method invocations.
We finally end up at Child; its initializer runs, then the constructor(s) run in order, and finally we're done.
Show me!
class Parent {
/* some utility methods so we can run this stuff */
static int print(String in) {
System.out.println("#" + in);
return 0;
// we use this to observe the flow.
// as this is a static method it has no bearing on constructor calls.
}
public static void main(String[] args) {
new Child(1, 2);
}
/* actual relevant code follows */
Parent(int arg) {
print("Parent-ctr");
print("the result of getNow: " + getNow());
}
int y = print("Parent-init");
long getNow() { return 10; }
}
class Child extends Parent {
Child(int a, int b) {
this(print("Child-ctr1-firstline"));
print("Child-ctr1-secondline");
}
int x = print("Child-init");
Child(int a) {
super(print("Child-ctr2-firstline"));
print("Child-ctr2-secondline");
}
final long now = System.currentTimeMillis();
#Override long getNow() { return now; }
}
and now for the great puzzler. Apply the above rules and try to figure out what this will print.
#Child-ctr1-firstline
#Child-ctr2-firstline
#Parent-init
#Parent-ctr
#the result of getNow: 0
#Child-init
#Child-ctr2-secondline
#Child-ctr1-secondline
Constructor execution ordering is effectively: the first line goes first, and the rest goes last.
a final field was 0, even though it seems like it should never be 0.
You always end up running your parent's constructor.
--
*) You can use them for locks or sentinel pointer values. Let's say 'mostly useless'.
**) You can hack a class file so that it describes a class without a parent class (not even j.l.Object); that's how java.lang.Object's class file works. But you can't make javac make this, you'd have to hack it together, and such a thing would be quite crazy and has no real useful purpose.
In inheritance, the construction of a child object depends on at least one parent constructor.
Calling the super () method is not mandatory. By default, Java will call the parent constructor without argument except if you precise a custom constructor.
Here an example
Mother
public class Mother {
int a;
public Mother() {
System.out.println("Mother without argument");
a = 1;
}
public Mother(int a) {
System.out.println("Mother with argument");
this.a = a;
}
}
child
public class Child extends Mother {
public Child() {
System.out.println("Child without argument");
}
public Child(int a) {
super(a);
System.out.println("Child with argument");
}
}
If you do this :
Child c1 = new Child();
you will get :
Mother without argument
Child without argument
If you do this :
Child c1 = new Child(a);
You will get :
Mother with argument
Child with argument
But if you change the second child constructor to and remove the super(arg) the parent constructor without argument will be called :
public Child(int a) {
// super(a);
System.out.println("Child with argument");
}
You will get :
Mother without argument
Child with argument
May be this course for beginners can help you Coursera java inheritance
I have a code-snippet, and I should determine what line I should un-comment so it will compile.
Question: Why only lines 9,13 and 10,14 works? Why wont 9,14 work for example? I'm a bit confused. help is highly appreciated! (Btw, the options are only un-commenting two lines of code)
1. // Question 3.1
2. class Car {
3. private Car() { }
4. protected Car(int x) { }
5. }
6. public class MG extends Car {
7. // MG(int x) { }
8. // MG(int x) { super(); }
9. // MG(int x) { super(x); }
10. // private MG(int x) { super(x); }
11. // MG() { }
12. // MG() { this(); }
13. // MG() { this(6); }
14. // MG() { super(7); }
15. public static void main(String[] args) {
16. new MG(7);
17. new MG();
18. } }
I believe the lack of understand comes from not enough familiarity of private constructor and protected access modifier, so I'm reading on that and I will also continue trying figuring it out.
Edit: Well I almost got it now, first of all line 8 cant be called so options with 8 and 11-14 are gone. line 7 - why can't it be called for e.g. with line 11? I believe MG(){} will be called but first the private car() has to be called, error. with line 12 not possible, because than I need line 11, with line 13 no idea why, with line 14 no idea why..
I wrote it on Ideone, because i was pretty sure that line 9 and 14 should work and they do!
Check it here (code)
The only important thing to remember in this example is, that if you do not invoke parent constructor, Java will invoke it in that manner "super()". Since your parent class non-parameter constructor is private, it won't compile.
That's why lines 7,8,11 are plain wrong.
Inheritance
Subclass by default get the access of all parent class methods, variables, constructor.
When you are going to create object of child class then (jvm calls zero parameter constructor implicitly)first parent class constructor executed and then child class constructor.
In your case you are calling super class constructor explicitly.
Use print statement in constructor you will get clear idea ...
First of all Few things to notice:
First get some idea about access modifiers:
About private constructor:
prevent subclassing (extending). If you make only a private constructor(only have one constructor), no class can extend your class, because it can't call the super() constructor. read more
And little bit about constructor:
Constructors are never inherited - they are specific to the class in
which they are defined.
If no constructor implemented, default constructor will added by the
compiler implicitly.
In subclasses did not call the super() compiler automatically add those to all the constructors.
When a new object that is a subclass is constructed, the constructor
for the superclass is always called first.
Constructor invocation maybe implicit or explicit.
explicit call to a constructor of superclass: super() - has to be the first statement in the subclass constructor.
Without any constructor in MG:
In this line public class MG extends Car { eclipse show error:
Implicit super constructor Car() is not visible for default
constructor. Must define an explicit constructor.
Because of inheritance you need to pass values to parent class constructor.
And for this new MG(7);:
The constructor MG(int) is undefined
Because you donot have any parameterized constructor in MG class.
UPDATE:
You said in your question you only want to know about line number 7, 11, 12, 13 and 14. But I will answer for all the lines. Then others who looking for answer also can understand
If you uncomment line number 7:
When we create an object of a child class always the constructor of the parent get completed and the constructor of the child runs later.
When you run the program, First in the main method new MG(7); object looking for matching constructor in the MG, which is MG(int x) {}. Inside this has super() which is compiler added one. Then compiler look for default constructor in parent class, It cannot find since default constructor is private.
To fix this: MG(int x) {super(x);}
If you uncomment line number 8:
When you run the program, First in the main method new MG(7); object looking for matching constructor in the MG, which is found.
MG(int x) {super()}
If you added super() or not compiler will add this. There is no different between these two:
MG(int x) {}
MG(int x) {super()}
If you uncomment line number 9:
This line is fine(no errors). First compiler looking for constructor(MG(int x) { super(x); } for object(new MG(7);). Then inside the constructor have called super(x) which is have one argument and it is match with the parent class constructor. As I mentioned before, parent class constructor execute first, Then child class constructor execute.
If you uncomment line number 10:
private MG(int x) { super(x); }
Access modifier is not affected because this class is a subclass and it is not a parent class for any class. And we can create object from calling private constructor. read more about private constructor.
If you uncomment line number 11:
MG() { }
It is match with the new MG(); object. Compiler have added super() but no matching constructor found in the parent class.
If you uncomment line number 12:
MG() { this(); }
First, lets look at what is this():
this can be used inside the Method or constructor of Class.
this works as a reference to the current Object whose Method or
constructor is being invoked.
The this keyword can be used to refer to any member of the current
object from within an instance Method or a constructor.
this() keyword can be used inside the constructor to call another
overloaded constructor in the same Class.
This is also called the Explicit Constructor Invocation.
And this() and super() both cannot use in one constructor.
So this line is unnecessary because you don't have any other MG() constructors. learn more about this.
If you uncomment line number 13:
MG() { this(6); }
This is also unnecessary or cannot be called unless you have another MG() constructor. If you do like this:
MG(){
this(6);
}
MG(int x){
super(x);
}
What happen here is when you run the program new MG(); object find the default constructor and in it call the parameterized constructor(MG(int x){}). Then in the this constructor take the value and send it to the parent class.
If you uncomment line number 14:
MG() { super(7); }
new MG(); is matched with the costructor and in it you have passed value 7 to the parent class parameterized constructor.
Done.
Given this Java code, this outputs 0 and 4:
class A{
A() { print(); }
void print() { System.out.println("A"); }
}
class B extends A{
int i = Math.round(3.5f);
public static void main(String[] args){
A a = new B();
a.print();
}
void print() { System.out.println(i); }
}
And with this identical C# code, this outputs 4 and 4
using System;
class A{
internal A() { print(); }
virtual internal void print() { Console.WriteLine("A"); }
}
class B : A{
int i = (int) Math.Round(3.5f);
public static void Main(string[] args){
A a = new B();
a.print();
}
override internal void print() { Console.WriteLine(i); }
}
Though I figure out that the output should be 4 and 4 on Java, but the answer is actually 0 and 4 on Java. Then I tried it in C#, the answer is 4 and 4
What gives? Java rationale is, during construction of B, A is still initializing(consequently I posit B is still initializing if Java said A is still initializing), so the default value should be 0. Hence the output is 0 and 4 in Java.
Why does C# constructor behavior differ from Java, or vice versa?
It's happening because of differences in the ordering of object initialisation in constructors.
What is happening in Java:
(empty, implicit) Constructor of B is called
Superclass Construtor of A is called (prints 0 since i is uninitialised)
i is initialised after the superclass constructor
print() is called (prints 4)
What is happening in C#:
(empty, implicit) Constructor of B is called
i is initialised before calling the superclass constructor
Superclass Construtor of A is called (prints 4 since i is already initialised)
print() is called (prints 4)
Neither is right or wrong - it's just a difference in how the compiler orders the construction operations. Personally I think the Java ordering is a marginally more logical, because it makes sense to me that the superclass is fully constructed before the subclass initialisation takes place.
Either way, because the logic can get quite complicated, I'd suggest that you avoid calling virtual methods during object construction in general.
The order of initialization in Java:
1.The storage of the instance is wiped to zero, automatically setting all the primitives in the object to their default values (zero for numbers and the equivalent for boolean and char) and the references to null.
2.The constructor of the base class A is called. It will the call the print method in class B, since it is an overridden method. i is 0 at this moment.
3.The member initialization of the class B is executed. So i is 4 now.
In order not to produce this kind of surprise, do not call any non-static or non-private methods in a constructor,since they may be overridden in derived classes.
In the following example:
class Base {
int x=10;
Base() {
show();
}
void show() {
System.out.print ("Base Show " +x + " ");
}
}
class Child extends Base {
int x=20;
Child() {
show();
}
void show() {
System.out.print("Child Show " + x +" ") ;
}
public static void main( String s[ ] ) {
Base obj = new Child();
}
}
Why is the output as shown below
Child Show 0 Child Show 20
I thought constructors can only access instance members once its super constructors have completed.
I think what is happening here is that the super constructor is calling the child's show() method because this method was overridden in Child. as it has been overridden but why is the value of x 0 and why is it able to access this method before the super constructor has completed?
I think what is happening here is that the super constructor is calling the child's show() method because this method was overriden in Child.
That is correct
but why is the value of x 0
because it's not initialized yet (x of Child)
and why is it able to access this method before the super constructor has completed?
That's exactly why in a constructor you should never call a method, which can be overridden (non-final public and protected).
Edit:
The strange thing here is that everything has default/ package-private visibility. This can have some strange effects. See: http://www.cooljeff.co.uk/2009/05/03/the-subtleties-of-overriding-package-private-methods/
I recommend to avoid overriding methods with default visibility if possible (you can prevent this by declaring them final).
You can call overriden methods from constructors, but it's bad and you shouldn't. You illustrated the reason why this is bad: the derived class doesn't get a chance to get initialized, so uninitialized fields will be used - in your example, the default for int x is 0, that's why it's printing 0.
constructor chaining it makes sense to explain exactly what that is. A subclass constructor method's first task is to call its superclass' constructor method. This ensures that the creation of the subclass object starts with the initialization of the classes above it in the inheritance chain.
http://java.about.com/b/2009/02/07/java-term-of-the-week-constructor-chaining.htm
http://javahours.blogspot.com/2008/12/constructor-chain.html
Childs override of the show method is invoked because that's what the Java spec calls for. Here is a great discussion of why you should not do it. The value of x is zero because Child has not finished initializing yet.
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);
}
}