• 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
  • Tim Cooke
  • Devaka Cooray
  • Ron McLeod
  • Jeanne Boyarsky
Sheriffs:
  • Liutauras Vilda
  • paul wheaton
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Piet Souris
  • Carey Brown
  • Tim Holloway
Bartenders:
  • Martijn Verburg
  • Frits Walraven
  • Himai Minh

When is a String a constant?

 
Ranch Hand
Posts: 1274
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi ranchers,

only the code in the static block of the second class is executed. Can I say, that the reason for this is that in Version1 s is a compile time constant whereas in Version2 it is not?


Output is:

one
String 1

two
static block, Version2
String 2



Does this have anything to do with the String pool?
Any comments welcome!

Yours,
Bu.


source: me (not from a mock exam)
 
Ranch Hand
Posts: 1710
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Burkhard,

The fact says that constants must be initialized where declared
or in the static block.

Your Version 1, value to the s is assigned at compile time; I see
that in the byte code too.

Version 2, reference to object is given at run time, obviously
because of "new" operator.
Before the reference variable is given the object in version 2,
the static block must complete, therefore you got the S.O.P statement
executed well before the String constructor is called.

Some observations:

1- "staic blocks are loaded with the class"
2- Version 1 and Version 2 classes are not loaded until you
called to print the constant values. (It is up to the class loader
to find when to load which class.)

And if the object were not String (immutable), of-course we could modify
that as well.

Correct me please If I do miss something.
[ April 29, 2007: Message edited by: Chandra Bhatt ]
 
Ranch Hand
Posts: 652
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi chandra,
How did the version2 class got loaded and why did the version1 class did not get loaded? :roll:
 
Chandra Bhatt
Ranch Hand
Posts: 1710
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My observation finds the following:

1- static blocks are called when the class is loaded.
2- When should class get loaded, the JVM finds out looking at some detail as
instantiation of an object. static blocks are executed very first.
3- In the Burkhards code the Main class is loaded first because it has the main method. If Main class extends class Version1 then static block of the Verison 1 class is executed first. (see it by doing); JVM manages to do so.
4- Only Version 2 class's static block is executed when main method tries to
access the constant s2.
The reason behind this is "constants can be initialized in the static block too besides where declared"
There are only two places where constants must be initialized:
a) Where declared or
b) in the static block
Otherwise compiler complains.

So for that sake, JVM executes the static block of the Version 2 class., because it may have some code that does initialization.

In the first case where the constant is compile time constant (reference variable is made referencing to the string object (no new operator used)).
So there is no need to the JVM to execute the static block of that, because that is compile time constant (already has been initialized)
[ April 29, 2007: Message edited by: Chandra Bhatt ]
 
Nik Arora
Ranch Hand
Posts: 652
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a doubt:

According to my observation say me if it is wrong:

Version1 class has a static initializer. There is a print statement in it. In the program it does not get printend means class Version1 has not got loaded. If class has not got loaded then how is that the constant in version1 is getting accessed in main method.

Explain me
 
Ranch Hand
Posts: 2412
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Also these statements from the Java Language Specification 12.4 determine when classes are initialized.

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, and an assert statement (�14.10) lexically nested
within T is executed.


In Version 1, the static variable refers to a compile-time constant.

In Version 2, the static variable does not refer to a compile-time constant.
 
Chandra Bhatt
Ranch Hand
Posts: 1710
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks a lot Keith,

You gave the real testimony to all above discussion!

for you!!!
 
Burkhard Hassel
Ranch Hand
Posts: 1274
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks to Keith from me as well.

The difficulty arose from the fact that in either case a new String object is made. But in the first case
static final String s = "String 1";

the new object is made without the use of the new operator.
The first String object can be looked at as a compile time constant. As the value is given at compile time and can never change - because Strings are immutable.


Normally, objects cannot be compile time constants (because a final object can be manipulated, it only cannot be dereferenced).
But String is an exception, because Strings are immutable. So Strings can be compile time constants.

In Version2, the new operator is used, and this is never done at compile, but at runtime, so no compile time constant. Despite the facts that Strings are immutable, and the value of the variable in Version2 can never change.

No compile time constant -> static block is executed.

Correct? (Well I'm sure about the line above )


Bu.
 
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The JLS defines a constant variable (shudder):

We call a variable, of primitive type or type String, that is final and initialized with a compile-time constant expression (�15.28) a constant variable.



The final String variable s = "String 1" is therefore a constant variable (shudder) , where as the one with a new String is not.

Notice that the definition of a constant variable (shudder) does not insist on the static qualifier.
[ May 01, 2007: Message edited by: Barry Gaunt ]
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[Bu]: Can I say, that the reason for this is that in Version1 s is a compile time constant whereas in Version2 it is not?

Yes.

The other posts go into detail as to why, but the answer to your original question was, indeed, a simple "yes".

[Bu]: Does this have anything to do with the String pool?

Sort of. Because s is a constant string in Version1, it goes in the String pool. But that's more of a run-time effect. The main reasoning is that, because s is a compile-time constant in Version1, it's value gets compiled directly into class Main. And at runtime, there's then no reason to load Version1 at all, as the value of Version1.s is already part of Main. That value is also incidentally in the String pool, but I don't think that's an important part of the explanation for this particular phenomenon.
 
We must storm this mad man's lab and destroy his villanous bomb! Are you with me tiny ad?
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic