Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Constructor vs instance initializer

 
Georgy Bolyuba
Ranch Hand
Posts: 162
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi

I'm confused a little about order of initialization. I've tried this:


As I expected, output was:


But then I've tried this code:


produses output like this:


My question is: "What should I think about innitialization order? (Constructor vs instance initializer)"

George.
 
David Harkness
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Both field initializer and instance initializer blocks taken in file order are copied to the beginning of each constructor that doesn't chain to another constructor of the same class.

This file (TestInstInit.java) demonstrates several cases.Here is its output:
 
Georgy Bolyuba
Ranch Hand
Posts: 162
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your example. So, David, let me ask you one more question.

If I get you rigth, this code:


is converted to this code:


I mean code will be _placed_ into constructor. Am I right?
[ February 24, 2005: Message edited by: George Bolyuba ]
 
Mike Gershman
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Both field initializer and instance initializer blocks taken in file order are copied to the beginning of each constructor that doesn't chain to another constructor of the same class.

Not quite. It is true that instance initializers are executed in source code order in an object just before the second line of the object's last constructor in order of execution ( the first line of that constructor is always super(...) ), but the rules are different. For example, the declare before read rule applies to initializers but not to constructors.

Check out this code:


Also, the handling of exceptions is different. A checked exception thrown in a constructor can be caught or thrown in that particular constructor ( and in any subclass constructors that call it via super(...) ). A checked exception in an instance initializer block must be declared in a throws clause of every constructor in the class (and at least one constructor must be explicitly declared). A checked exception thrown by an instance variable initializer is illegal. These special rules don't apply in anonymous classes.
[ February 24, 2005: Message edited by: Mike Gershman ]
 
Georgy Bolyuba
Ranch Hand
Posts: 162
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

It is true that instance initializers are executed in source code order in an object just before the second line of the object's last constructor in order of execution


( the first line of that constructor is always super(...) )

That's it. I was asking right about it. But now I have another question: "Is it correct that any constructor (not chained) receives a copy of byte-code wich is generated by a compiler for each field initializer and instance initializer block?"


Also, the handling of exceptions is different. A checked exception thrown in a constructor can be caught or thrown in that particular constructor ( and in any subclass constructors that call it via super(...) ). A checked exception in an instance initializer block must be declared in a throws clause of every constructor in the class (and at least one constructor must be explicitly declared). A checked exception thrown by an instance variable initializer is illegal. These special rules don't apply in anonymous classes.

Hm... I cannot get how can I catch an exception thrown in a super() constructor? Can you give a code exapmple?

In TIJ (3 Ed.) Bruce Eckel writes that he does not know the way to catch an exception thrown by super();.
 
David Harkness
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by George Bolyuba:
I cannot get how can I catch an exception thrown in a super() constructor?
I just verified it with JDK 1.5, and having "super();" in a try block gives the error:
 
Mike Gershman
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's it. I was asking right about it. But now I have another question: "Is it correct that any constructor (not chained) receives a copy of byte-code wich is generated by a compiler for each field initializer and instance initializer block?"

That is not how it works. Here is the jvm spec for the process. The jvm calls the initializers separately.
http://java.sun.com/docs/books/vmspec/2nd-edition/html/Concepts.doc.html#19124

Hm... I cannot get how can I catch an exception thrown in a super() constructor? Can you give a code exapmple?

In TIJ (3 Ed.) Bruce Eckel writes that he does not know the way to catch an exception thrown by super();.

Exceptions thrown in constructors are caught or thrown in the code that created the object. Checked exceptions thrown by constructors must be thrown in all subclass constructors in the chain of invocation down to the constructor directly named in the object creation expression.

 
Georgy Bolyuba
Ranch Hand
Posts: 162
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Exceptions thrown in constructors are caught or thrown in the code that created the object.

Yeah. I know that. But I cannot catch excaption, thrown by super() inside the constructor, that calls super();
 
Mike Gershman
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But I cannot catch exception, thrown by super() inside the constructor, that calls super();

Correct.

The first line of a constructor is specially handled by the jvm. It is "executed" before the object exists and is mainly used to define a path from the constructor named in the instance initialization expression to the Object constructor and to pass initialization values upward. The real construction occurs when the constructors return to their callers, creating a path of constructor execution from Object to the class being constructed, with the initializers being called by the jvm before the constructors of each class get to execute.

I think the restrictions on the first line of the constructor are intended to limit the number of cases the jvm has to handle. If you could start a constructor with a try statement, you would need catch clauses and/or finally clauses. But they could only contain super(...) and this(...) statements, not System.out.println() or anything else (think about it). Is this limited additional functionality worth the extra logic required in the jvm? The Java designers didn't think so.
 
Georgy Bolyuba
Ranch Hand
Posts: 162
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok. Thx. I think I get it now.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic