File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes Constructor vs instance initializer Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Constructor vs instance initializer" Watch "Constructor vs instance initializer" New topic
Author

Constructor vs instance initializer

Georgy Bolyuba
Ranch Hand

Joined: Feb 18, 2005
Posts: 162
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.


SCJP 1.4 (100%) Done.<br />SCJD (URLyBird 1.2.3 Started)
David Harkness
Ranch Hand

Joined: Aug 07, 2003
Posts: 1646
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

Joined: Feb 18, 2005
Posts: 162
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

Joined: Mar 13, 2004
Posts: 1272
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 ]

Mike Gershman
SCJP 1.4, SCWCD in process
Georgy Bolyuba
Ranch Hand

Joined: Feb 18, 2005
Posts: 162

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

Joined: Aug 07, 2003
Posts: 1646
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

Joined: Mar 13, 2004
Posts: 1272
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

Joined: Feb 18, 2005
Posts: 162

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

Joined: Mar 13, 2004
Posts: 1272
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

Joined: Feb 18, 2005
Posts: 162
Ok. Thx. I think I get it now.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Constructor vs instance initializer