Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
133 views
in Technique[技术] by (71.8m points)

java - Why "abc" in String x = "abc".toUpperCase() is not included in an intern pool?

Whenever I do a string conversion (like to uppercase - using toUpperCase()), does a new string object always get created (not using interning)? Also, I tried to test something myself with the code below:

String x = "abc".toUpperCase();
String y = "abc";
String z = "ABC";
System.out.println(x == y); // returns false
System.out.println(x == z); // returns false

I thought "abc" would put an object into an intern pool while toUpperCase() seems to be just using new keyword without String.intern(). However, it did not go as I expected. x == y gave me a false value. Why "abc" is not pushed into an intern pool? I thought calling a string using a literal format -e.g. "abc" - would do like new String("abc").intern() automatically?

question from:https://stackoverflow.com/questions/65932382/why-abc-in-string-x-abc-touppercase-is-not-included-in-an-intern-pool

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Just to clarify, I assume here that the main point of your question was comparing x == z - two uppercase strings - and not x == y which would always be false because one is uppercase and the other is lowercase and this has nothing to do with interning.

JVMS 8 5.1 says:

A string literal is a reference to an instance of class String, and is derived from a CONSTANT_String_info structure (§4.4.3) in the binary representation of a class or interface. The CONSTANT_String_info structure gives the sequence of Unicode code points constituting the string literal.

The Java programming language requires that identical string literals (that is, literals that contain the same sequence of code points) must refer to the same instance of class String (JLS §3.10.5). In addition, if the method String.intern is called on any string, the result is a reference to the same class instance that would be returned if that string appeared as a literal. Thus, the following expression must have the value true:

("a" + "b" + "c").intern() == "abc"

To derive a string literal, the Java Virtual Machine examines the sequence of code points given by the CONSTANT_String_info structure.

If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String.

Otherwise, a new instance of class String is created containing the sequence of Unicode code points given by the CONSTANT_String_info structure; a reference to that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.

The important parts here is that only string literals are put in a so called string pool and ones on which .intern() is explicitly called. Same goes to "taking" instances from the string pool. So if a string is created in any other way than specified as a string literal or is recieved from intern() method, it won't be an instance from string pool nor it will be added there.

A following example shows a little bit better how it works:

String a = "abc".toUpperCase().intern();
String b = "abc".toUpperCase();
String c = "ABC";
String d = "ABC";

System.out.println(a == b); // returns false
System.out.println(a == c); // returns true
System.out.println(b == c); // returns false
System.out.println(c == d); // returns true

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...