This week's book giveaway is in the Testing forum.
We're giving away four copies of Data Structures the Fun Way: An Amusing Adventure with Coffee-Filled Examples and have Jeremy Kubica on-line!
See this thread for details.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Tim Cooke
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Devaka Cooray
  • Ron McLeod
  • paul wheaton
Saloon Keepers:
  • Tim Moores
  • Piet Souris
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Frits Walraven
  • Scott Selikoff

Confused scenarios in Java while loop, dead code and unreachable code

 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Everyone...

In Eclipse for the following code, line 1 and 3 mark as dead code, and line 2 gives a compilation error.



[Also when executed javap -c Test (after commented out the code block that gives the compilation error), it is evident that JDK has omitted the unreachable code.]

I don't understand why line 2 gets a compilation error, while other two don't.

Why compiler omit 1 and 3 related code? How compiler possibly know at the compile time they are dead code, if this.flag and new Test().flag are not considered as compile-time constants by the compiler?

Thanks in advance...
 
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
flag is final, so the compiler is smart enough to know it's value won't change

To answer your question on why it's different, have a look at lazy instantiation in java
 
Marshal
Posts: 76845
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch both of you.
 
Campbell Ritchie
Marshal
Posts: 76845
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sam Knowski wrote:. . . have a look at lazy instantiation in java

Please explain. What has lazy initialisation got to do with it?
 
Sam Knowski
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Please explain. What has lazy initialisation got to do with it?



Please correct me if I'm wrong, but from my understanding the local variable (final boolean flag = false) is instantiated at compile time. However, the two object references (Test().flag and this.flag) are instantiated lazily (during runtime) to save memory.

Therefore 2 will be recognized by the compiler as dead code, however 1 and 3 could not be recognized until runtime.
 
Sam Knowski
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Welcome to the Ranch both of you.


Thank you!
 
author
Posts: 23928
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

First, welcome to the ranch...

Pavithra Gunasekara wrote:
I don't understand why line 2 gets a compilation error, while other two don't.

Why compiler omit 1 and 3 related code?



The definition of unreachable code is very specific. It is defined clearly by the Java Language Specification... along with the fact that it is a compile error.

The eclipse compiler is actually smarter than the JLS, in looking for unreachable code.... Unfortunately, it will be violating the JLS, if it reports it as an unreachable code compile error. Hence, the eclipse compiler reports it as dead code, and provides it as only a warning error.

Pavithra Gunasekara wrote:
How compiler possibly know at the compile time they are dead code, if this.flag and new Test().flag are not considered as compile-time constants by the compiler?



Interestingly, they are compile time constants. Final variables, of the primitive type, that are assigned during declarations, to a compile time constant expression, are considered constant variables. And constant variables are compile time constants.

Henry
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Henry Wong wrote:Final variables, of the primitive type ... are considered constant variables.


Isn't that an oxymoron? Either a field is a constant or a variable, isn't it?

Trouble is (at least as far the JLS is concerned), I suspect you're right.

@Pavithra: Listen to Henry. He's the guru of constants and all things compile-time.

Winston
 
Campbell Ritchie
Marshal
Posts: 76845
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sam Knowski wrote:. . . the local variable (final boolean flag = false) is instantiated at compile time. However, the two object references (Test().flag and this.flag) are instantiated lazily (during runtime) to save memory. . . .

Nothing is instantiated until run time. And that is not what lazy initialisation means. Lazy initialisation means that something is not initialised or only initialised partiallly when it is required. The opposite is eager initialisation which means it is initialised completely in advance of being required.
What does happen at compile time is that formulae which fulfil the definition in the JLS which Henry showed you of a constant expression are evaluated at compile time. Look at this silly little class:-You can compile it and print the bytecode like this:-
javap -c Print2_5
… getting this output:-Nowhere in there will you find any sign of 1 2 3 or 4. You will however find 2.5 in the statement numbered 3. That is because constant expressions are evaluated before compilation completes. That also means that if you have a public constant which is a comile‑time constant, you should never change it.

Additional: This is the relevant JLS section.
 
Ranch Hand
Posts: 239
12
Scala IntelliJ IDE Eclipse IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

Sam Knowski wrote:. . . the local variable (final boolean flag = false) is instantiated at compile time. However, the two object references (Test().flag and this.flag) are instantiated lazily (during runtime) to save memory. . . .



Nothing is instantiated until run time . . .



Not to split hairs but I wonder about nothing is instantiated until runtime. In the below code, isn't MY_CONST instantiated to an instance of Double at compile time? I could be wrong...

 
Campbell Ritchie
Marshal
Posts: 76845
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No.

Actually a double might be a compile‑time constant but if you look in the JLS you find that a Double isn't.
The values for the constants may be in the bytecode but neither the Class<T> object nor the T object exists before runtime. So they cannot be instantiated earlier, surely? The static field is initialised when the class is loaded when the JVM runs.
 
Pavithra Gunasekara
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you very much, everyone for your answers and this has been a very useful discussion for me to understand the topic more broadly
 
Scott Shipp
Ranch Hand
Posts: 239
12
Scala IntelliJ IDE Eclipse IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:No.

Actually a double might be a compile‑time constant but if you look in the JLS you find that a Double isn't.
The values for the constants may be in the bytecode but neither the Class<T> object nor the T object exists before runtime. So they cannot be instantiated earlier, surely? The static field is initialised when the class is loaded when the JVM runs.



Yes it seems it happens when the JVM loads the class based on Google searching.

So, is the definition of runtime the same as "when the class is loaded"? Because I was thinking that a class could get loaded into the JVM but then not ran yet.

And I remember hearing that the JSR says only primitives can be compile-time constants, but check it out, this code compiles just fine and I am making up a totally random class Pizza.


 
Pavithra Gunasekara
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Welcome to the Ranch both of you.



Thank you
 
Pavithra Gunasekara
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:

Henry Wong wrote:
@Pavithra: Listen to Henry. He's the guru of constants and all things compile-time.



Yes, I find his answer very interesting... Thanks to you both...

 
Henry Wong
author
Posts: 23928
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Scott Shipp wrote:
And I remember hearing that the JSR says only primitives can be compile-time constants, but check it out, this code compiles just fine and I am making up a totally random class Pizza.



Compile time constants can be either a primitive or a String. And in your example, the Pizza instance is not a compile time constant.

Henry
 
Ranch Hand
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am confused here.. If they are not compile time constants then how come static final variable re-initialize.

I was an impression that we can't reinitialize static final variables. It will not be reinitialize. But here it looks like it is getting reinitialize twice. First during compile time (default value) and other and run time.

I may be wrong completely.
 
Sam Knowski
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Nothing is instantiated until run time. And that is not what lazy initialisation means. Lazy initialisation means that something is not initialised or only initialised partiallly when it is required. The opposite is eager initialisation which means it is initialised completely in advance of being required.
What does happen at compile time is that formulae which fulfil the definition in the JLS which Henry showed you of a constant expression are evaluated at compile time. Look at this silly little class:-You can compile it and print the bytecode like this:-
javap -c Print2_5
… getting this output:-Nowhere in there will you find any sign of 1 2 3 or 4. You will however find 2.5 in the statement numbered 3. That is because constant expressions are evaluated before compilation completes. That also means that if you have a public constant which is a comile‑time constant, you should never change it.

Additional: This is the relevant JLS section.



Thank you for clarifying Campbell, my mistake!
 
Campbell Ritchie
Marshal
Posts: 76845
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Scott Shipp wrote:. . . Yes it seems it happens when the JVM loads the class based on Google searching.

So, is the definition of runtime the same as "when the class is loaded"? Because I was thinking that a class could get loaded into the JVM but then not ran yet. . . .

Beware of simply googling. You never know whether you will strike gold or dross. The full details are in the JLS but that can be difficult to read sometimes.
Runtime means when you run the JVM, which you usually start with the java tool. It terminates when all Threads terminate. If you name a class in code which is being executed, then that class will be loaded and a Class<T> object created representing that class. Static fields will be loaded (but not instance fields at this stage). If you have code initialising a static field, that will be executed too and values given to that fieldThe first time you execute code naming that class, e.g. private Foo f;, the Foo class will be loaded, the Class<Foo> object created, and those two fields initialised. Note one of them is used as a global constant but is not a constant expression; the other is not a constant but is initialised to the result of a constant expression. The name field is an instance field and only has existence when the class is instantiated, e.g f = new Foo(...);

You do not run classes. You can load them and instantiate them and you can run their methods, but you never run the class.
 
Henry Wong
author
Posts: 23928
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tushar Goel wrote:I am confused here.. If they are not compile time constants then how come static final variable re-initialize.

I was an impression that we can't reinitialize static final variables. It will not be reinitialize. But here it looks like it is getting reinitialize twice. First during compile time (default value) and other and run time.



A few points here...

1. Let's not confuse variables which are holding constant values (meaning the variable do not change) with "constant variables". The later is very specifically defined in the JLS. Also, constant variables are compile time constants, which means that their values are known at compile time. The former may be variables holding constants, but they may not be known at compile time.

2. The "final" and "static" modifiers, and whether they can/will reinitialize, are a different discussion. Arguably, final variables hold constant values, but that does not mean that they are constant variables. The modifier is only one of the many requirements to be a constant variable.

3. As for the discussion regarding the "default" value, and then initialized at runtime, I will assume that you are referring the part in the JLS on how final variables are initialized? ... if so, take a look at that part of the JLS again. You will notice the phrase "that are not constant variables", meaning the initialization process does *not* apply to constant variables.

Henry
 
Campbell Ritchie
Marshal
Posts: 76845
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Henry Wong wrote:. . . final variables hold constant values, but that does not mean that they are constant variables. . . .

Example:-
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Example...


Hmmm. A bit contrived, I'd say. word[0] is not the same thing as word, constant or not.

Furthermore, as we are fond of telling newbies, Java is "pass by value" - ALWAYS - so just because you can't change a reference doesn't mean you can't change the thing it points to. And as we are also fond of pointing out: an array in Java is an object.

Personally, I'd say that the JLS is to blame here, by confusing us with terms like 'constant' and 'variable' that don't mean the same thing they do in English (or indeed, many other computer languages).

@Pavithra: Unfortunately, you're stuck with it; so listen to Henry (and Campbell of course ... when he's right ).

Winston
 
Campbell Ritchie
Marshal
Posts: 76845
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:. . . A bit contrived, I'd say. . . .

Of course it is contrived. But it shows that the array pointed to is not a constant; although it cannot be reassigned it can change its state.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Of course it is contrived. But it shows that the array pointed to is not a constant; although it cannot be reassigned it can change its state.


Yes, but that would then apply to any reference type (except String, which looks like it's clearly been made a special case).

And what about:
  private final PlanetEnum earth = PlanetEnum.EARTH;
Is that a 'variable constant'? Or indeed a compile-time constant? Seems like it ought to be.

I simply don't like the business of slapping two seemingly exclusive adjectives together to make a noun - particularly when either one of them can be either an adjective OR an noun anyway.

IMO, it would have been a whole lot better if the JLS had simply used the word 'field' to denote a class or static member that is not a method or a nested declaration; and then used 'variable' and 'constant' the way most of us understand them - but for some reason Java documents seem to have an aversion to the word 'field'.

My 2¢

Winston
 
Scott Shipp
Ranch Hand
Posts: 239
12
Scala IntelliJ IDE Eclipse IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
After all that I have no idea what the definition of "compile-time constant" is or what practical difference it has from a "final static" variable.
 
Campbell Ritchie
Marshal
Posts: 76845
366
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A compile‑time constant (properly called constant expression) is handled differently by the compiler.Compile those two classes and view the bytecode with javap -c Kettle
This is what you get:-Note there is no reference to Temperatures.ANYTHING. What you find is the value: 100. Now try to change the Temperatures class to Fahrenheit… and compile it with javac Temperatures.java. Then repeat the javap call and you find the value is unchanged at 100.

That means that compile‑time constants are evaluated by the javac tool rather than their references being passed over. If you made that a public static final variable not pointing to a compile‑time constant, that would not happen. Go back to the Temperatures class and change the declaration from int to Integer, and see what happens. Remember an Integer does not count as a constant expression.
 
Scott Shipp
Ranch Hand
Posts: 239
12
Scala IntelliJ IDE Eclipse IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:A compile‑time constant (properly called constant expression) is handled differently by the compiler. . . . Remember an Integer does not count as a constant expression.



Now that resolves any confusion! Thanks!
 
Campbell Ritchie
Marshal
Posts: 76845
366
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome

Don't quote the whole of a post as a routine; that is unnecessary since you can read it one page above. I have removed most of the quote.
 
Henry Wong
author
Posts: 23928
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Scott Shipp wrote:After all that I have no idea what the definition of "compile-time constant" is or what practical difference it has from a "final static" variable.



I did a write up of what is a compile time constant a few years ago...

https://coderanch.com/t/454384/java/java/compile-time-constant

As for an example of the difference, here is a practical example that does not require a recompile of a class ... take these two static fields...


The first declaration is a constant variable. The second declaration is not a constant variable (and hence, not a compile time constant).

Now, take this snippet of code...

Notice that the use of the variable x in a case statement works, while the use of variable y does not? This is because the case statement requires the use of a constant expression.

Hope this helps,
Henry
 
Clowns were never meant to be THAT big! We must destroy it with this tiny ad:
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic