Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Non static block and constructor

1 view
Skip to first unread message

asit

unread,
Feb 28, 2009, 8:36:30 AM2/28/09
to
yesterday I read ab Non Static block.

I tried the following code

public class NonSta
{
int i;
NonSta()
{
System.out.println("Constructor");
i++;
System.out.println(i);
}
{
System.out.println("Non Static Block");
i += 10;
System.out.println(i);
add(100);
new NonSta();
}
void add(int k)
{
System.out.println("Add Block");
i += k;
System.out.println(i);
}
public static void main(String args[])
{
NonSta n = new NonSta();
}
}

I found that it becomes an infinite loop if the non static block
contains a call to constructor.

Does it logically imply "Non static block can't contain a
constructor".

Plz reply me !!!

Arne Vajhøj

unread,
Feb 28, 2009, 9:27:33 AM2/28/09
to

You will have to check the JLS and the JVM spec to find out what
exactly is specified for this case.

It seems obvious to me that it should not work well.

The static initializer should start and complete before
any instances of the class is created.

So creating an instance in the static initialized does
not make any sense to me.

Whether it should be a compile time error or a runtime
error or what runtime error must be in the specs somewhere.

Arne

Lew

unread,
Feb 28, 2009, 10:08:16 AM2/28/09
to
asit wrote:
>> yesterday I read ab [sic] Non Static [sic] block.

"ab"?

>> I tried the following code
>>
>> public class NonSta
>> {
>> int i;
>> NonSta()
>> {
>> System.out.println("Constructor");
>> i++;
>> System.out.println(i);
>> }
>> {
>> System.out.println("Non Static Block");
>> i += 10;
>> System.out.println(i);
>> add(100);
>> new NonSta();
>> }
>> void add(int k)
>> {
>> System.out.println("Add Block");
>> i += k;
>> System.out.println(i);
>> }
>> public static void main(String args[])
>> {
>> NonSta n = new NonSta();
>> }
>> }
>>

>> I found that it becomes an infinite loop if the non static [sic] block


>> contains a call to constructor.

It's not a loop.

>> Does it logically imply "Non static block [sic] can't contain a
>> constructor".

It should be obvious that a constructor cannot contain a constructor for
objects of the same class.

Arne Vajhøj wrote:
> It seems obvious to me that it should not work well.
>
> The static initializer should start and complete before
> any instances of the class is created.

It's a *non*-static initializer.

Calling a constructor inside a constructor is bound to fail. How can it ever
conclude?

asit, the non-static initializer block is part of the constructor. The
constructor tries to construct another object of the type that it's
constructing. That object tries to construct yet another object in its
constructor. And so on, /ad infinitum/. No constructor can ever finish.

I'm sure if you think about it you'll figure out why this cannot succeed.

--
Lew

Arne Vajhøj

unread,
Feb 28, 2009, 10:15:11 AM2/28/09
to
Lew wrote:

> asit wrote:
>>> I tried the following code
>>>
>>> public class NonSta
>>> {
>>> int i;
>>> NonSta()
>>> {
>>> System.out.println("Constructor");
>>> i++;
>>> System.out.println(i);
>>> }
>>> {
>>> System.out.println("Non Static Block");
>>> i += 10;
>>> System.out.println(i);
>>> add(100);
>>> new NonSta();
>>> }
>>> void add(int k)
>>> {
>>> System.out.println("Add Block");
>>> i += k;
>>> System.out.println(i);
>>> }
>>> public static void main(String args[])
>>> {
>>> NonSta n = new NonSta();
>>> }
>>> }
>>>
>>> I found that it becomes an infinite loop if the non static [sic] block
>>> contains a call to constructor.

>>> Does it logically imply "Non static block [sic] can't contain a


>>> constructor".
>
> It should be obvious that a constructor cannot contain a constructor for
> objects of the same class.
>
> Arne Vajhøj wrote:
>> It seems obvious to me that it should not work well.
>>
>> The static initializer should start and complete before
>> any instances of the class is created.
>
> It's a *non*-static initializer.

Ooops.

Then the rest of my reply does not make much sense.

Arne

PS: Weird construct - I have never used it or seen it used.

Lew

unread,
Feb 28, 2009, 10:23:48 AM2/28/09
to
Lew wrote:
>> It's a *non*-static initializer.

Arne Vajhøj wrote:
> PS: Weird construct - I have never used it or seen it used.

It's handy when you want to initialize something as part of construction, the
initialization is rather complex (e.g., involves temporary variables), there
is more than one constructor, and the initialization is common to all the
constructors.

--
Lew

John B. Matthews

unread,
Feb 28, 2009, 10:45:14 AM2/28/09
to
In article
<79cfb1cd-ff6b-4e5e...@r36g2000prf.googlegroups.com>,
asit <lip...@gmail.com> wrote:

[...]


> I found that it becomes an infinite loop if the non static block
> contains a call to constructor.

Yes, your program recursively invokes the constructor in an instance.
Here is a simpler version of the same problem. Try running it with an
artificially small heap to see the effect, e.g.:

java -Xms1M -Xmx1M InstanceInitializer

Contrast this with a static initializer:

<http://java.sun.com/docs/books/tutorial/java/javaOO/initial.html>
<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.6>
<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.7>

<code>
public class InstanceInitializer {

private static int count; {
System.out.print(++count + ", ");
new InstanceInitializer();
}

public static void main(String args[]) {

InstanceInitializer n = new InstanceInitializer();
}
}
<code>



> Does it logically imply "Non static block can't contain a
> constructor".

No. Infinite recursion is a programming error.

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

John B. Matthews

unread,
Feb 28, 2009, 10:58:12 AM2/28/09
to
In article <gobku4$ggd$3...@news.albasani.net>, Lew <no...@lewscanon.com>
wrote:

The difference bit me the other day when I intended to have a static
initializer but neglected the keyword. A static initializer would have
completed as part of class initialization, but the errant instance
initializer was happening later. I switched to a private static method.

Joshua Cranmer

unread,
Feb 28, 2009, 11:37:04 AM2/28/09
to
asit wrote:
> public class NonSta
> {

> {
> System.out.println("Non Static Block");
> i += 10;
> System.out.println(i);
> add(100);
> new NonSta();
> }

If you look at the actual bytecode, you will notice that this becomes
part of the constructor. So you have created infinite recursion.

I believe the proper name is an instance initialization block, but I
don't have my JLS reference up.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

Patricia Shanahan

unread,
Feb 28, 2009, 11:43:07 AM2/28/09
to
Lew wrote:
...

> Calling a constructor inside a constructor is bound to fail. How can it
> ever conclude?
...

How does this differ from any other recursive call? This program runs,
and terminates, despite the new Node instance expression inside the Node
constructor.

public class RecursiveConstructor {
public static void main(String[] args) {
Node node = new Node(3);
while(node != null){
System.out.println(node+" "+node.count);
node = node.next;
}
}
}

class Node{
Node next;
int count;
Node(int listLength){
count = listLength;
if(listLength > 1){
next = new Node(listLength-1);
}
}
}

John B. Matthews

unread,
Feb 28, 2009, 12:13:51 PM2/28/09
to
In article <nospam-A5D43B....@news.aioe.org>,

"John B. Matthews" <nos...@nospam.invalid> wrote:

...recursively invokes the constructor in an instance [initializer].

Oops, I forgot to check if I any words out.

[...]

Mark Space

unread,
Feb 28, 2009, 12:22:19 PM2/28/09
to
asit wrote:

> I found that it becomes an infinite loop if the non static block
> contains a call to constructor.
>
> Does it logically imply "Non static block can't contain a
> constructor".


"Can't" is a bit strong. It's a bad idea, usually. The following is
also a bad idea:

class Wtf {
public static void main( String ... args ) {
main( args );
}
}

but I could possibly think of a few reasons to call the main entry point
recursively, so "can't" is too strong, just you didn't do it correctly,
or for the right reason.

Lew

unread,
Feb 28, 2009, 1:12:00 PM2/28/09
to
Patricia Shanahan wrote:
> Lew wrote:
> ...
>> Calling a constructor inside a constructor is bound to fail. How can
>> it ever conclude?
> ...
>
> How does this differ from any other recursive call? This program runs,
> and terminates, despite the new Node instance expression inside the Node
> constructor.

There was no terminating condition in the OP's situation.

--
Lew

Patricia Shanahan

unread,
Feb 28, 2009, 1:23:16 PM2/28/09
to

Of course. It is that lack of an appropriate bound on the recursion,
rather than the fact of new instance creation during new instance
creation for the same class, that caused the stack overflow.

I was just pointing out that calling a constructor inside a constructor
is not *bound* to fail. As with any other recursive call, it fails or
not depending on whether there are appropriate limits on the recursion.

Patricia

Lew

unread,
Feb 28, 2009, 1:37:40 PM2/28/09
to
Lew wrote:
>> There was no terminating condition in the OP's situation.

Patricia Shanahan wrote:
> Of course. It is that lack of an appropriate bound on the recursion,
> rather than the fact of new instance creation during new instance
> creation for the same class, that caused the stack overflow.
>
> I was just pointing out that calling a constructor inside a constructor
> is not *bound* to fail. As with any other recursive call, it fails or
> not depending on whether there are appropriate limits on the recursion.

But it is not "as with any other recursive call". Constructors are not methods.

You are correct to point out that it was the lack the terminating condition
that was the trouble, but my words were in the specific context of the O.P.'s
example.

Beyond that, it is not smart to construct another instance of a class within
the constructor of that class. This is not like calling a recursive method;
constructors are fundamentally different from methods. Constructors are for
the purpose of constructing the 'this' instance, and pretty much always cause
trouble when they exceed that mandate. Can you think of a case where it's
ever a good idea to construct an additional instance from within the constructor?

--
Lew

Peter Duniho

unread,
Feb 28, 2009, 1:55:22 PM2/28/09
to
On Sat, 28 Feb 2009 10:37:40 -0800, Lew <no...@lewscanon.com> wrote:

> [...]


> Beyond that, it is not smart to construct another instance of a class
> within the constructor of that class.

Why not? Other than the general difficulty of getting recursion correct,
what's the problem? How is constructing an instance of the object
currently being constructed any worse than constructing an instance of any
other object? Or are you suggesting that when constructing the instance
of an object, you should not construct _any_ instance of _any_ object?

> This is not like calling a recursive method;

It's very much like that. Not all recursion involves a method calling
itself directly. In some cases, the recursion is less direct, and this
scenario is exactly such a scenario.

> constructors are fundamentally different from methods.

In some ways they are exactly like any other method. What is it about the
differences that do exist that make you believe you should not construct a
new instance of an object in the constructor?

> Constructors are for the purpose of constructing the 'this' instance,
> and pretty much always cause trouble when they exceed that mandate.

But if constructing another instance of the object being constructed is an
essential part of the construction of the object, why shouldn't it be in
the constructor?

> Can you think of a case where it's ever a good idea to construct an
> additional instance from within the constructor?

Sure. Consider a recursive data structure represented in a string (or
other data structure) passed to the constructor. Each constructor would
extract from the string whatever information pertains to the immediate
instance, creating any children indicated by the string, and passing to
those children whatever information remains in the string and is pertinent
to the construction of those children.

Eventually the string will be exhausted, the recursion will stop, all of
the constructors will exit normally and you'll be left with your recursive
data structure.

I'm not suggesting this is a common pattern. But I see no reason to rule
it out entirely.

Pete

blue indigo

unread,
Mar 1, 2009, 4:29:18 PM3/1/09
to
On Sat, 28 Feb 2009 13:37:40 -0500, Lew wrote:

> Patricia Shanahan wrote:
>> I was just pointing out that calling a constructor inside a constructor
>> is not *bound* to fail. As with any other recursive call, it fails or
>> not depending on whether there are appropriate limits on the recursion.
>
> But it is not "as with any other recursive call".

It is too.

> Beyond that, it is not smart to construct another instance of a class within
> the constructor of that class.

I mostly agree with Peter Duniho's objections to this statement, but I'd
like to add that the tail-recursive construction of Node in Patricia
Shanahan's (since snipped by someone) example code is, while not
conventional for Java (where I would tend myself to use a static factory
method), exactly the norm for constructing things like that in lisp.

--
blue indigo
UA Telecom since 1987

Arne Vajhøj

unread,
Mar 2, 2009, 9:16:04 PM3/2/09
to

It saves lines.

But I like to be able to read the sequence of lines in a constructor
without having to read in the JLS whether those non-static initializer
lines are executed first or last.

Arne

Arne Vajhøj

unread,
Mar 2, 2009, 9:24:32 PM3/2/09
to
Peter Duniho wrote:
> On Sat, 28 Feb 2009 10:37:40 -0800, Lew <no...@lewscanon.com> wrote:
>> [...]
>> Beyond that, it is not smart to construct another instance of a class
>> within the constructor of that class.
>
> Why not? Other than the general difficulty of getting recursion
> correct, what's the problem? How is constructing an instance of the
> object currently being constructed any worse than constructing an
> instance of any other object? Or are you suggesting that when
> constructing the instance of an object, you should not construct _any_
> instance of _any_ object?

It adds the risk of making an infinite recursion.

It is a difference.

And we don't need an "other" to justify it not being good.

>> Constructors are for the purpose of constructing the 'this' instance,
>> and pretty much always cause trouble when they exceed that mandate.
>
> But if constructing another instance of the object being constructed is
> an essential part of the construction of the object, why shouldn't it be
> in the constructor?

I think that experience has shown that constructors should be kept
simple to bring object in consistent state and not to contain major
logic.

>> Can you think of a case where it's ever a good idea to construct an
>> additional instance from within the constructor?
>
> Sure. Consider a recursive data structure represented in a string (or
> other data structure) passed to the constructor. Each constructor would
> extract from the string whatever information pertains to the immediate
> instance, creating any children indicated by the string, and passing to
> those children whatever information remains in the string and is
> pertinent to the construction of those children.
>
> Eventually the string will be exhausted, the recursion will stop, all of
> the constructors will exit normally and you'll be left with your
> recursive data structure.

I would code that in another way.

I don't like the idea of new X() triggering half the codebase. A simple
constructor and a buildTree method would make the code easier to
understand.

Arne

Lew

unread,
Mar 2, 2009, 10:07:00 PM3/2/09
to

A good point, that has two solutions I can think of immediately that let you
still use instance initializer blocks. Get over your prejudice against
knowing the language in detail, or code those lines so they can be executed
either first or last without harm.

Otherwise, don't use them. Just because the language supports a feature
doesn't mean you have to use it. If you do use it, it behooves you to
understand the implications.

--
Lew

Arne Vajhøj

unread,
Mar 2, 2009, 10:15:10 PM3/2/09
to

It is not only the original author - it is also all the
maintenance programmer that have to touch the code for a decade
or two.

The best code is not code that uses every subtle feature of the
language - the best code is code that everyone can read even without
knowing the language.

Arne

Peter Duniho

unread,
Mar 3, 2009, 1:57:43 PM3/3/09
to
On Mon, 02 Mar 2009 18:24:32 -0800, Arne Vajhøj <ar...@vajhoej.dk> wrote:

> Peter Duniho wrote:
>> On Sat, 28 Feb 2009 10:37:40 -0800, Lew <no...@lewscanon.com> wrote:
>>> [...]
>>> Beyond that, it is not smart to construct another instance of a class
>>> within the constructor of that class.
>>
>> Why not? Other than the general difficulty of getting recursion
>> correct, what's the problem? How is constructing an instance of the
>> object currently being constructed any worse than constructing an
>> instance of any other object? Or are you suggesting that when
>> constructing the instance of an object, you should not construct _any_
>> instance of _any_ object?
>
> It adds the risk of making an infinite recursion.

That is not "other than the general difficulty of getting recursion
correct".

I asked a very specific question. Do you have an answer for _that_
question or not?

> It is a difference.

Of course it's a difference. Any constructor that is not identical has "a
difference". That wasn't my question.

> And we don't need an "other" to justify it not being good.

Sure you do. Otherwise, all constructors or all recursion are "not being
good" (depending on what your specific objection is).

Since we have and accept both as normal programming tactics, obviously
there's something _other_ than simply being a constructor or simply being
recursion that makes it "not being good".

>>> Constructors are for the purpose of constructing the 'this' instance,
>>> and pretty much always cause trouble when they exceed that mandate.
>>
>> But if constructing another instance of the object being constructed
>> is an essential part of the construction of the object, why shouldn't
>> it be in the constructor?
>
> I think that experience has shown that constructors should be kept
> simple to bring object in consistent state and not to contain major
> logic.

True. But irrelevant. Some constructors are more complex than others,
and complexity is not in and of itself an argument against itself.

>>> Can you think of a case where it's ever a good idea to construct an
>>> additional instance from within the constructor?
>>
>> Sure. Consider a recursive data structure represented in a string (or
>> other data structure) passed to the constructor. Each constructor
>> would extract from the string whatever information pertains to the
>> immediate instance, creating any children indicated by the string, and
>> passing to those children whatever information remains in the string
>> and is pertinent to the construction of those children.
>>
>> Eventually the string will be exhausted, the recursion will stop, all
>> of the constructors will exit normally and you'll be left with your
>> recursive data structure.
>
> I would code that in another way.

That all depends on the specific implementation. I would code it in the
simplest way, and I agree that most often that would preclude recursion
from the constructor. But, until you've examined every possible example
of where recursion from a constructor could be useful, and shown why
there's a different, better implementation, you have not proved that one
should never do recursion from a constructor.

> I don't like the idea of new X() triggering half the codebase.

I'll take "half" as an intentional exaggeration. In fact, recursion is
_more_ efficient, precisely because it _doesn't_ require additional
methods to be called.

Like it or not, constructors often do complicated things, with or without
recursion. Any time you create another object in a constructor, even of a
type different from the one being constructed, you introduce calls to
other parts of the codebase, including other constructors. Those calls
might lead to yet more calls to yet more parts of the codebase.

> A simple constructor and a buildTree method would make the code easier to
> understand.

In some cases, maybe it would. In other cases, perhaps not. But, the
recursive solution involves just the call to the constructor, whereas your
suggested "buildTree" method requires a call to the constructor and a call
to the "buildTree" method. If that isn't a step toward your hypothesized
"triggering half the codebase", I don't know what is.

Pete

0 new messages