"Small" Program Challenge.

L

Lew

Wrong. Loading and initialization go hand-in-hand.


What?

See JLS 12.4, which I cited upthread:
<http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4>
"A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

- T is a class and an instance of T is created.

- T is a class and a static method declared by T is invoked.

- A static field declared by T is assigned.

- A static field declared by T is used and the field is not a constant variable (§4.12.4).

- T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.

A reference to a static field (§8.3.1.1) causes initialization of only the class or interface that actually declares it, even though it might be referred to through the name of a subclass, a subinterface, or a class that implements an interface.

Invocation of certain reflective methods in class Class and in package java..lang.reflect also causes class or interface initialization.

A class or interface will not be initialized under any other circumstance."
Wrong. Loading and initialization go hand-in-hand.

Not according to the JLS. What authority are you using?
You haven't cited anything except my own post, and your quotation of
*that* was a jumbled mess with some sections repeated for some reason.

Again, I quoted the section I re-quoted in this post. I provided the link
*and* quoted the relevant content. How can you say I didn't?
On your part, Lew.


Wrong. Loading and initialization go hand-in-hand.

Except according to the JLS.
And not before.

When invoking a static method of a non-loaded class, the standard
procedure always has been:

Load the class.
Initialize the class.

Note - that is two steps, not one.
Invoke the method.

In particular, the spec requires that in this:

class A {
static int x;

static { x = 100; }

static int foo () { return x; }
}

a call to A.foo() should return 100, not 0. If it can attempt to invoke
foo before the static initializer has executed that would be violated.

It can attempt to call 'foo()' before the initializer has executed. This is
exactly one of the circumstances that causes the initializers to execute.

Read the JLS! I have referenced and quoted the relevant section twice now.
On the other hand, it complaining that a reflective call to A.bar()
can't be resolved sooner than the loading and initializing of A as part
of trying to resolve bar is equally anomalous. If it hasn't loaded and

I haven't seen any examples of reflection in this thread. Regardless,
"certain reflective methods" invoked will cause initialization.
 
L

Lew

This is the case that seems to be applicable here. It should not be
erroring out trying to invoke main until after initialization, because
the initialization must occur immediately *before* the invocation
attempt (since it must have occurred if that attempt succeeds or again
the spec is violated).


That's backwards. Initialization must *precede* the invocation, not

Invocation precedes initialization, in that it is one of the triggers for
initialization, as described in the JLS.

The attempt to invoke causes initialization before invocation completes.

I've provided a link and citation of the relevant JLS section. Twice.
Read it.
*follow* it. The JVM is required to initialize the class just *before*
attempting to invoke the main method, and indeed up through Java 6 that
is precisely what it did.

No, it is initialized just before the method is invoked. The attempt is what
triggers the initialization.

And initialization doesn't occur until such an attempt or one of the other
triggering events. In particular, the class is not automatically initialized
when loaded.

Read the JLS.
 
L

Lew

Leif said:
Might this be what is happening? The JLS doesn't seem to specify _how_
the main method should be invoked, so might not a Java implementation
do so through reflection and thus trigger the initialization of the
class?

There was no 'main()' method in the example under discussion.

The JLS says that the JVM is started by invocation of a 'main()' method.

Without such an invocation, nothing should have been able to call any of the
static methods of the 'enum' or otherwise triggered initialization of that class.

The class initialized anyway.

Ergo the process didn't follow the JLS.
 
J

javax.swing.JSnarker

See JLS 12.4, which I cited upthread:

Why did you write half a sentence and end it in mid-word, though?
Not according to the JLS. What authority are you using?

The fact that initialization is required before use of a class
(instantiation, invocation of a static method, whatever), and that
loading is not required until the circumstances that permit and require
initialization. Thus, loading will tend not to occur until right before
use, and initialization will thus tend to occur right after loading.
Again, I quoted the section I re-quoted in this post. I provided the link
*and* quoted the relevant content. How can you say I didn't?

You didn't provide any link and you quoted some stuff from my post
*twice*, for some reason. There seems to be a partial quote of it and a
bit of inline commentary from you (criticisms, natch), followed by a
second attribution line and then a quote of the entirety of my post,
including the parts already quoted earlier.
Except according to the JLS.

The fact that initialization is required before use of a class
(instantiation, invocation of a static method, whatever), and that
loading is not required until the circumstances that permit and require
initialization. Thus, loading will tend not to occur until right before
use, and initialization will thus tend to occur right after loading.
Note - that is two steps, not one.

However, there is little point in doing the first step until right
before the second step, so in practice they should occur back-to-back.
It can attempt to call 'foo()' before the initializer has executed.

No, it generally can't. If the attempt succeeds and, as a consequence,
foo() executes before the initializer has executed, then foo will
incorrectly return 0. Therefore the attempt must not be made until the
initializer has executed, except in the peculiar case that the attempt
is known in advance to be guaranteed to fail. In which case there should
have been a compile-time error earlier still.
This is exactly one of the circumstances that causes the initializers
to execute.

You are confused. You seem to be thinking the order is

Load class
Attempt to call foo
Initialize class

But this can only be guaranteed not to violate the semantic requirements
if the attempt is known to be sure to fail. If the attempt to call foo
might succeed, then the order MUST be

Load class
Initialize class
Attempt to call foo

so that if the third step succeeds and foo begins executing, foo does
not encounter things still in an uninitialized state that the spec
guarantees must have been initialized before foo begins executing!
Read the JLS! I have referenced and quoted the relevant section twice now.

And I've replied to it once, and it clearly states that initialization
must occur *before* any invocation of a static method. Your suggestion
that it can invoke it first and *then* initialize the class simply
cannot fly.
I haven't seen any examples of reflection in this thread.

How is the main method invoked? It obviously isn't a statically-compiled
call from another class, and the only other invocation mechanism is
reflection; therefore it is called reflectively, by something that
behaves analogously to
Class.forName(argv[1]).getMethod("main",ARRAY_OF_JUST_THE_STRING_ARRAY_CLASS).invoke(null,convertRestOfArgv);.

Why is the above quoted, but not responded to?
 
J

javax.swing.JSnarker

There was no 'main()' method in the example under discussion.

The JLS says that the JVM is started by invocation of a 'main()' method.

Without such an invocation, nothing should have been able to call any of the
static methods of the 'enum' or otherwise triggered initialization of that class.

There is such an invocation, though -- albeit an unsuccessful one, if no
method of that name can be resolved by the reflection code.
The class initialized anyway.

Because the two alternatives are:

initialize, then try to invoke method; and
try to invoke method, then initialize.

But in the second case, if the invocation succeeds the method runs and
then the initializer instead of the other way around, and that's
obviously wrong.
 
J

javax.swing.JSnarker

Well no, you have the option to load a class without initializing it.

I assume that the change was to prevent bugs. If parts of a real
working application start up in a class initialization (not best
practice, but still possible) which allocate resources and then those
resources are not cleaned up when the whole app abruptly terminates, I
could see how it could be considered a bug in the JVM's start-up
procedure rather than the app itself. I'm not sure I'd agree, but I
could see someone making that case.

If resources allocated by an app are not cleaned up when "the whole app
abruptly terminates", then the bug is in the operating system, not the
app OR the JVM.
 
J

javax.swing.JSnarker

Invocation precedes initialization, in that it is one of the triggers for
initialization, as described in the JLS.

That's confused thinking. Invocation *cannot* precede initialization if
initialization must have been done before the method's code starts
running. It can't run the method *before* initialization.

The language of the spec does not say, however, that invocation will be
followed by initialization. As you quoted it above, it clearly says that
initialization will occur *immediately before invocation* in these
cases. Initialization first, THEN invocation.

The trigger is not invocation itself, as it can't be as initialization
would then happen one invocation too late. The trigger is that that
invocation (attempt) is imminent, but has not yet already happened.
The attempt to invoke causes initialization before invocation completes.

That also doesn't make sense. The attempt to invoke and the execution,
if the attempt is successful, of the method are all one single thing.
Initialization either happens before or after it -- and it cannot happen
after. Therefore it happens before.

If I attempt to catch a ball and then put on my baseball glove, then the
ball will land in my bare hand if the attempt succeeds. If I put on my
baseball glove and then attempt to catch a ball, the ball will land in
my gloved hand if the attempt succeeds. The spec says the ball should
land in my gloved hand. So, I can wait until immediately before
attempting to catch the ball to put the glove on, but I cannot wait
until after the attempt. (And if the analogy with the JLS spec is
continued, I mustn't put the glove on until immediately before the first
such attempt.)
I've provided a link and citation of the relevant JLS section. Twice.
Read it.

I did. If anyone didn't read it it was you. It clearly said
initialization *precedes* the first of any of a number of things done to
a class, including method invocation. Your notion that method invocation
can happen first and initialization later is based on nothing in the
written text of the spec, and, furthermore, simply does not make sense.
No, it is initialized just before the method is invoked.

There you are, then. *Before* the method is invoked. Not after. And
certainly not during. (None of this stuff is thread-safe!) Initialize,
then (attempt to) invoke method. Cannot be the other way around, or the
ball will land in an ungloved hand if the attempt succeeds.
And initialization doesn't occur until such an attempt or one of the other
triggering events.

But then it occurs immediately *before*.
In particular, the class is not automatically initialized when loaded.

No, but in practice it's not loaded until right before it would be
initialized, because it would just be wasting memory during the interim.
Read the JLS.

You read it. Or reread it. Obviously you missed something or got confused.
 
L

Lew

javax.swing.JSnarker said:
You read it. Or reread it. Obviously you missed something or got confused.

Not only did I not miss something nor am confused, I've encountered this in
practice.

You argue that usually loading immediately precedes initialization. This is
true. But not always.

You argue that loading must precede initialization. This is true, but it is
not true that initialization must immediately follow loading.

For example, a reference to 'Foo.class' will load 'Foo', but not initialize it,
if 'Foo' had not previously been loaded or initialized.

The big gaping flaw in your reasoning is that you leave out what triggers the
cycle of load/initialize. Classes are loaded and initialized on demand in Java.
That means the loading and initialization does not happen until there is
a qualifying reference to the class.

I've encountered bugs in code that depended on initialization to occur
immediately upon loading. What a surprise when that doesn't happen,
as in fact does happen.

Unless of course you understand the JLS.

I keep quoting and requoting the JLS, section 12.4.1. You should read it.
You obviously missed something or got confused.
 
J

javax.swing.JSnarker

Not only did I not miss something nor am confused, I've encountered this in
practice.

You argue that usually loading immediately precedes initialization. This is
true. But not always.

Why would it ever be done earlier? The class would just be taking up
space in main memory but not accomplishing anything useful by being
there right up until it was about to be used, at which time it would
need to be initialized.
The big gaping flaw in your reasoning is
nonexistent.

I keep quoting and requoting the JLS, section 12.4.1. You should read it.
You obviously missed something or got confused.

I did not. It is you that did. You seem to think it's possible for
someone to wait until after they attempt to catch a ball to put their
ball glove on, and yet have the ball land in a gloved hand if the catch
is successful. That, right there, is all the evidence we need of your
confused state.
 
G

Gene Wirchenko

[snip]
I keep quoting and requoting the JLS, section 12.4.1. You should read it.
You obviously missed something or got confused.

javax.swing.JSnarker:

Either Lew is correct here, or he is not.

If he is correct, then you should listen to him.

If he is not and since he is a fairly on-the-ball sort, then it
is a confusing area, and you would be better off to not code in such a
way as to depend on such a confusing area.

The C equivalent of your argument is someone arguing that void
main() works on his system. (main() is defined in the C standard as
returning int on a hosted system (i.e. running under an OS).)

Sincerely,

Gene Wirchenko
 
J

javax.swing.JSnarker

[snip]
I keep quoting and requoting the JLS, section 12.4.1. You should read it.
You obviously missed something or got confused.

javax.swing.JSnarker:

Either Lew is correct here, or he is not.

If he is correct, then you should listen to him.

If he is not and since he is a fairly on-the-ball sort, then it
is a confusing area, and you would be better off to not code in such a
way as to depend on such a confusing area.

The C equivalent of your argument is someone arguing that void
main() works on his system. (main() is defined in the C standard as
returning int on a hosted system (i.e. running under an OS).)

Void main() is not supported by the C specification. However, the quoted
section of the JLS clearly states that initialization precedes
invocation (which is also just plain common sense).
 
D

David Lamb

You are confused. You seem to be thinking the order is

Lew quoted the JLS. You ought to be arguing with its words, not his. I
don't pretend to have dug into the issue far enough to argue it one way
or another, but what matters isn't what any specific implementation
does, nor what you or Lew or I thinks the semantics *ought* to be. What
matters is what the JLS says.

If you start addressing the spec instead of Lew, I'll keep reading.
 
A

Andreas Leitgeb

javax.swing.JSnarker said:
However, the quoted
section of the JLS clearly states that initialization precedes
invocation (which is also just plain common sense).

Obviously, the JVM can determine availability of a static method
in a class that is loaded, but not yet initialized. Thus, during
bootstrapping the application, it *can* load the specified class,
notice lack of an appropriate main method, and skip initialization,
as it would be obviously futile for the resulting task of throwing
an exception.

Your parable about catching a ball with or without gloves falls
flat, because the JVM can freeze the ball mid-air, while calculating
its chances to catch it and then put the gloves on only in positive
case.

I must admit, I liked the old behaviour for the sake of really simple
almost boilerplate-lean way of testing some trivial bits of code.
class Test { static { /* code */ } }
(admittedly, the enum-approach never occurred to me)
I wouldn't even care for the method-lookup exception in those cases.

Otoh, I can also understand that this doesn't win over the bare fact
that non-existence of a static method can be detected without initia-
lizing the class, and thus still doing so is against the spirit of
lazy initialization.
 
G

Gene Wirchenko

On Mon, 18 Jun 2012 22:12:50 -0400, "javax.swing.JSnarker"

[snip]
Void main() is not supported by the C specification. However, the quoted
section of the JLS clearly states that initialization precedes
invocation (which is also just plain common sense).

1) It is "void", not "Void", and

2) more importantly, "void main()" is legal C, just not in a hosted
implementation. Since the usual use of C is under a hosted
implementation, "void main()" is something to avoid in general, but
only in general.

Why not just read the JLS instead using "common sense" and
baseball gloves?

Sincerely,

Gene Wirchenko
 
J

javax.swing.JSnarker

Lew quoted the JLS. You ought to be arguing with its words, not his. I
don't pretend to have dug into the issue far enough to argue it one way
or another, but what matters isn't what any specific implementation
does, nor what you or Lew or I thinks the semantics *ought* to be. What
matters is what the JLS says.

And the JLS *clearly* says that initialization *precedes* invocation.
 
J

javax.swing.JSnarker

Obviously, the JVM can determine availability of a static method
in a class that is loaded, but not yet initialized.

Not relevant.
Thus, during bootstrapping the application, it *can* load the
specified class, notice lack of an appropriate main method, and skip
initialization, as it would be obviously futile for the resulting
task of throwing an exception.

The spec doesn't specify any such behavior. Checking for existence of a
method is part of invoking a method (when the invocation is reflective
rather than compiled), and invoking a method follows initialization.
Your parable about catching a ball with or without gloves falls
flat,

You are incorrect.
Otoh, I can also understand that this doesn't win over the bare fact
that non-existence of a static method can be detected without initia-
lizing the class, and thus still doing so is against the spirit of
lazy initialization.

Even were the spec to allow it, optimizing for the rare case (main
method not found) rather than for the common case is always premature
optimization, and premature optimization is the root of all evil.
 
J

javax.swing.JSnarker

On Mon, 18 Jun 2012 22:12:50 -0400, "javax.swing.JSnarker"

[snip]
Void main() is not supported by the C specification. However, the quoted
section of the JLS clearly states that initialization precedes
invocation (which is also just plain common sense).

1) It is "void", not "Void", and

Yes, I know, however it was at the start of a sentence and part of
English prose rather than compilable code.
2) more importantly, "void main()" is legal C,

Not according to any of the books I've read, and there have been many.
Why not just read the JLS instead using "common sense" and
baseball gloves?

I read the JLS *as well*. The JLS clearly stated that initialization
*precedes* invocation. It does not follow it and it certainly does not
happen *during* it, as some recent posts to this thread seem to have
suggested.
 
G

Gene Wirchenko

On Mon, 18 Jun 2012 22:12:50 -0400, "javax.swing.JSnarker"

[snip]
Void main() is not supported by the C specification. However, the quoted
section of the JLS clearly states that initialization precedes
invocation (which is also just plain common sense).

1) It is "void", not "Void", and

Yes, I know, however it was at the start of a sentence and part of
English prose rather than compilable code.

Since it is a code example, English grammar does not apply.
Not according to any of the books I've read, and there have been many.

What about the C standard? You have snipped my qualifying
phrase. "void main()" is valid under a non-hosted implementation. I
expect that most C programmers are not using it that way, and that is
why your books do not cover it. The C standard does though.

You have missed the fine point of the argument I have given. This
leads me to believe you have likely missed it in the Java argument of
this thread.
I read the JLS *as well*. The JLS clearly stated that initialization
*precedes* invocation. It does not follow it and it certainly does not
happen *during* it, as some recent posts to this thread seem to have
suggested.

Why would people argue over something that is clearly stated?
Although Lew is somewhat abrasive, he has established credibility. You
do not. I know how I would bet.

Sincerely,

Gene Wirchenko
 
J

javax.swing.JSnarker

On Mon, 18 Jun 2012 22:12:50 -0400, "javax.swing.JSnarker"

[snip]

Void main() is not supported by the C specification. However, the quoted
section of the JLS clearly states that initialization precedes
invocation (which is also just plain common sense).

1) It is "void", not "Void", and

Yes, I know, however it was at the start of a sentence and part of
English prose rather than compilable code.

Since it is a code example, English grammar does not apply.

"Void main() is not supported by the C specification." is English prose,
not a code example.
What about the C standard?

I assume that the books follow the C standard, or at least the vast
majority of them do. As for the standard itself, for some peculiar
reason it doesn't seem to be available anywhere by simple point, click,
download free of charge, unlike the JLS.
You have missed the fine point of the argument I have given.

I have done nothing of the sort, or anything wrong at all, and I will
thank you to stop publicly smearing me by claiming or suggesting
otherwise in news posts.
Why would people argue over something that is clearly stated?

I do not know why Lew is arguing over something that is clearly stated.
I have a guess (that he's throwing up a smokescreen rather than admit
he's wrong) but no proof that it's correct.
 
G

Gene Wirchenko

On 19/06/2012 12:12 PM, Gene Wirchenko wrote:
On Mon, 18 Jun 2012 22:12:50 -0400, "javax.swing.JSnarker"

[snip]

Void main() is not supported by the C specification. However, the quoted
section of the JLS clearly states that initialization precedes
invocation (which is also just plain common sense).

1) It is "void", not "Void", and

Yes, I know, however it was at the start of a sentence and part of
English prose rather than compilable code.

Since it is a code example, English grammar does not apply.

"Void main() is not supported by the C specification." is English prose,
not a code example.

Oh, but it is. It is only prohibited in a hosted implementation.

CLUE: There is a reason why I keep qualifying my statement with
"hosted" or "non-hosted".
I assume that the books follow the C standard, or at least the vast
majority of them do. As for the standard itself, for some peculiar
reason it doesn't seem to be available anywhere by simple point, click,
download free of charge, unlike the JLS.

I have seen plenty that suggest "void main()" in a hosted
implementation. It is the first thing that I look for in evaluating
quality.
I have done nothing of the sort, or anything wrong at all, and I will
thank you to stop publicly smearing me by claiming or suggesting
otherwise in news posts.

You keep missing the distinction that I keep making about hosted
and non-hosted implementations.

I am not smearing you; I am making a point that you keep ignoring
while claiming to understand.
I do not know why Lew is arguing over something that is clearly stated.
I have a guess (that he's throwing up a smokescreen rather than admit
he's wrong) but no proof that it's correct.

I think it more likely that it is you who is wrong. I await your
next smokescreen post.

Sincerely,

Gene Wirchenko
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Programming Challenge 2
Virtuous Hacking challenge 13
Tutorial challenge program help 19
small program 49
JFrame stays unusably small in applet 5
Tasks 1
[Challenge] Cookie Monster! 6
Html download challenge 25

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top