Win a copy of Zero to AI - A non-technical, hype-free guide to prospering in the AI era this week in the Artificial Intelligence and Machine Learning forum!
  • 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Paul Clapham
  • Bear Bibeault
  • Jeanne Boyarsky
Sheriffs:
  • Ron McLeod
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Jj Roberts
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • salvin francis
  • Scott Selikoff
  • fred rosenberger

String Constant pool puzzle

 
Ranch Hand
Posts: 62
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Sheriff
Posts: 9674
42
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the first case since you are concatenating two literal values, the compiler can do the concatenation and JVM will have the value in the pool. And since both the literal values are same, both string variables are pointing to the same value in the pool. In the second case since there is a variable involved, compiler cannot do the concatenation. At runtime JVM will do the concatenation and in that case the value doesn't go into the pool.
 
Ng Sharma
Ranch Hand
Posts: 62
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please explain step by step..!
 
Marshal
Posts: 70602
287
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The two Strings you are concatenating in line 4 are compile time constants; s3 (line 7) is not a compile time constant because it isn't marked final.

Remember that knowing the nice details of the String pool is absolutely essential......until you pass your cert exam, when you can forget everything you ever knew abut it.
 
Saloon Keeper
Posts: 12405
269
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think Ankit's explanation was very clear. Tell us what you don't understand.
 
Ranch Hand
Posts: 95
1
VI Editor Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote: s3 (line 7) is not a compile time constant because it isn't marked final.



I would argue that s3 is compile-time constant, since it is initialized with literal value, but s4 is not compile-time constant, because it is constructed by concatenating literal value and String variable...

So I think the essential difference is, that s2 is compile-time constant, since it is created by concatenation of literal values, whereas s4 is created by concatenation of literal and String variable. And btw, s1 wold not equal s4 even if s4 was created same way as s2, since you have mismatch in s4 literal value, see "Supermna" vs "Superman".
 
Campbell Ritchie
Marshal
Posts: 70602
287
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Miroslav Lehotsky wrote:. . . I would argue that s3 is compile-time constant . . .

I am afraid that is incorrect. There is a compile time constant on that line, but it is the "" after the assignment sign. The variable s3 is not a constant of any kind, because it isn't marked final.

. . . s4 is created by concatenation of literal and String variable. . . .

Yes, that is correct: s3 is a variable which may change its contents.
 
Miroslav Lehotsky
Ranch Hand
Posts: 95
1
VI Editor Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

Miroslav Lehotsky wrote:. . . I would argue that s3 is compile-time constant . . .

I am afraid that is incorrect. There is a compile time constant on that line, but it is the "" after the assignment sign. The variable s3 is not a constant of any kind, because it isn't marked final.

. . . s4 is created by concatenation of literal and String variable. . . .

Yes, that is correct: s3 is a variable which may change its contents.



It seems you're right, I didn't verified it before but with slight modification of introducing keyword final before declaration of s3 variable, it changes the result of second comparison from false to true, eg:

 
Campbell Ritchie
Marshal
Posts: 70602
287
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, if you mark s3 with the final modifier, it becomes a compile time constant too. You will find all the gory details in the Java® Language Specification (=JLS), where you will learn the official term is, “constant expression”. In the present case, look on s3 as a simple name (penultimate • point).
The explanation for the behaviour of the == operatoris given by the next line:-

That JLS section wrote:Constant expressions of type String are always "interned" so as to share unique instances, using the method String.intern.

 
Campbell Ritchie
Marshal
Posts: 70602
287
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

About three hours ago, I wrote:. . . until you pass your cert exam, when you can forget everything you ever knew abut it.

It is usually bad design to use the == operator in real life code.

When I was doing my MSc, there was one of our number who had written a lot of C#, where == is overloaded on Strings. He complained that his code worked nicely with lots of Strings, until it was serialised and deserialised. He used lots of String literals, so all his String variables pointed to interned Strings, and == would return true for identical Strings. But the serialised version wouldn't work, because the Strings weren't the interned objects any more. I told him that and said to change == to equals() throughout. Fortunately I was correct and it worked thereafter.
 
Stephan van Hulst
Saloon Keeper
Posts: 12405
269
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:The variable s3 is not a constant of any kind, because it isn't marked final.


It's effectively final though, and that's the requirement for it to count as a sub-expression of a constant expression.
 
Campbell Ritchie
Marshal
Posts: 70602
287
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The JLS section I linked to earlier says it must be marked final in order to be a constant expression (or part of one). That section links to this JLS part,which says,

A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28).

Their \texttt{} text.
It doesn't say anything about effectively final variables. It also doesn't say whether the initialisation has to be on declaration or whether it may be done later.
 
Stephan van Hulst
Saloon Keeper
Posts: 12405
269
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was mistaken.

I interpreted the reference that §15.28 made to §4.12.4 as that both final and effectively final variables can be constant variables.
 
Miroslav Lehotsky
Ranch Hand
Posts: 95
1
VI Editor Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I also presumed that compiler would handle both final and effectively final the same way. Good to know though, it can be seen, there is still a lot of stuff that neither OCP covers.
 
Campbell Ritchie
Marshal
Posts: 70602
287
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Miroslav Lehotsky wrote:. . . there is still a lot of stuff that neither OCP covers.

There are so many weird things in the JLS that it would be impossible for the exam to cover them all. The meaning of constant variables does have a real‑life use, however:-Now, if you try to change the temperatures to the original temperature sale (Fahrenheit):-...you can break somebody's code. You can actually have newly‑compiled code using Fahrenheit and older code running with Celsius. I found that in one of Joshua Bloch's books; I forget which one. That problem shouldn't occur (at least I think not) with the following temperature class:-I have assumed this is a very old class and written it in the JDK1.4.2 idiom

Remember that one of the original Java™ buzzwords was “Simple”? I hardly think that the definition of constant variables was simple, even before the concept of effectively final variables was added.
 
Miroslav Lehotsky
Ranch Hand
Posts: 95
1
VI Editor Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, I stumbled upon this scenario before, the thing is, that Java is inlining such constant in calling code, so if you recompile only the constants class, it does not have effect on calling code. Thats why constants should not be used this way, but rather via getters. But the approach you're mentioning, with usage of big Integer is working also via only constants class recompilation, didn't know that.
 
Campbell Ritchie
Marshal
Posts: 70602
287
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I used Integer, not BgInteger. If you go through the JLS section in question, you will find that the third version of my Temperatures class obscures any compile time constants. A getXXX() method as you suggested (good idea ) doesn't return a compile time constant either. My use of the Integer class uses the same principle.
An alternative design is to decide, “Once a constant, always a constant,” which means non‑private compile time constants must never change after they have been published.
 
Miroslav Lehotsky
Ranch Hand
Posts: 95
1
VI Editor Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I used Integer, not BgInteger...



I expressed myself badly, by 'big Integer' i meant int wrapper => Integer, not very suitable choice of words in this context...
 
Ng Sharma
Ranch Hand
Posts: 62
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


lang1 and lang2 pointing a same reference.
Why s3 is not using a unreference String Object.
StringConstantPool.png
[Thumbnail for StringConstantPool.png]
StringConstantPool
 
Campbell Ritchie
Marshal
Posts: 70602
287
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What gives you the idea that your 0‑length String in line 4 is recorded anywhere? The 0‑length String from line 7 will however be stored somewhere.
 
Stephan van Hulst
Saloon Keeper
Posts: 12405
269
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your diagram doesn't make sense. There are no duplicates in the String pool.
 
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Coder

== is not suitable for comparing string. The right way to compare two strings is the equals method.
as not s1 == s2 but s1.equals (s2).




regards kiuziu
 
Greenhorn
Posts: 1
Debian Suse Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Ng Sharma wrote:




You misspelled superman in line 8.
 
Campbell Ritchie
Marshal
Posts: 70602
287
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch
 
Ankit Garg
Sheriff
Posts: 9674
42
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Alexandros Collie wrote:You misspelled superman in line 8.


That's a great catch

However even if you spell it correctly, the output won't change. The compiler changes String s2 = "Superman" + ""; to String s2 = "Superman"; as at compile time it knows the result of the concatenation. This happens for any String concatenation with literals. So if you wrote String s2 = "Super" + "man";, the compiler will change this to String s2 = "Superman";...
 
Nothing up my sleeve ... and ... presto! A tiny ad:
Thread Boost feature
https://coderanch.com/t/674455/Thread-Boost-feature
reply
    Bookmark Topic Watch Topic
  • New Topic