[Turn] Java in a special type String

Java in String is a special wrapper class data created in two forms:

  1. String s = "abc";
  2. String s = new String("abc");

In a first stack to create a reference variable s String object class, and then to find out whether "abc" is stored in the string constant pool, if not then create three char-stack value 'a' , 'b', 'c', and then creates a String object in the heap object, whose value is just an array of three values ​​of type char created in the stack consisting of { 'a', 'b', 'c'} , then the object is stored string object into a string constant pool, the s-point to the last address of the object, if the "abc" has been stored in a string constant pool, then find a value of "abc" in a string constant pool target object, then the address of the object point s.

The first features: JVM automatically according to the actual situation of the stack data to determine whether it is necessary to create new objects.

The second can be decomposed into two steps 1, String object = "abc"; 2, String s = new String (object); a first step of creating a reference to the first embodiment, while the second step due to the "abc" has been created and save the string constant pool, so jvm heap will only create a new string object, there are three type char value of its share value stack.

The second characteristic: not and will create a new object in the heap, regardless of its string value is equal, whether it is necessary to create new objects.

Before talking about string comparisons, we must understand the difference between == and the equals:
because all java classes inherit from the base class Object, and Object in use == equals to achieve, so equals and == is the same, are more target address, where the Java API classes override most of the equals method, comprising the basic data type of package type, String the like. For class == Address String String used to compare two objects, equals to the content (value) compare two String object.

Use string constant pool

String s0 = "abc"; 
String s1 = "abc"; 
System.out.println(s0==s1); //true  可以看出s0和s1是指向同一个对象的。

String == and equals the difference in the

String s0 =new String ("abc"); 
String s1 =new String ("abc"); 
System.out.println(s0==s1); //false 可以看出用new的方式是生成不同的对象 
System.out.println(s0.equals(s1)); //true 可以看出equals比较的是两个String对象的内容(值)

Compile OK

String s0="helloworld"; 
String s1="helloworld"; 
String s2="hello" + "word"; 
System.out.println( s0==s1 ); //true 可以看出s0跟s1是同一个对象 
System.out.println( s0==s2 ); //true 可以看出s0跟s2是同一个对象

Analysis: Because the example in s0 and s1 in the "helloworld" are string constants, they are determined at compile time, so that s0 to s1 == true; and "hello" and "world" are also strings constant, when a string connected together by a plurality of string constant, the string constant and certainly its own, so also in the compilation of s2 is parsed to a string constant, so that s2 is the constant pool "helloworld" a reference. So we have come to s0 == s1 == s2;

Compile time can not be determined

String s0="helloworld"; 
String s1=new String("helloworld"); 
String s2="hello" + new String("world"); 
System.out.println( s0==s1 ); //false  
System.out.println( s0==s2 ); //false 
System.out.println( s1==s2 ); //false

Analysis: created with new String () string is not constant, it can not be determined at compile time, so the new string String () to create not put into the constant pool, which has its own address space.
s0 is the constant pool "helloworld" references, s1 because they can not determine at compile time, so is the "helloworld" a reference to the new object is created at runtime, s2 because of the latter part of new String ( "world") so it can not compile OK, it is also a reference to the newly created objects "helloworld" of;

Compiler optimization

String s0 = "a1"; 
String s1 = "a" + 1; 
System.out.println((s0 == s1)); //result = true  
String s2 = "atrue"; 
String s3= "a" + "true"; 
System.out.println((s2 == s3)); //result = true  
String s4 = "a3.4"; 
String s5 = "a" + 3.4; 
System.out.println((a == b)); //result = true

Analysis: compile the program, the JVM will constant string "+" connected to optimize the value after the connection, to take "a" + 1, the compiler optimization after the class is already in a1. At compile time value is established as a string constant, so the above procedure the end result are true

Compile time can not be determined

String s0 = "ab"; 
String s1 = "b"; 
String s2 = "a" + s1; 
System.out.println((s0 == s2)); //result = false

Analysis: JVM for string reference, since "+" is connected, the string of the string reference exists, the value of the program is compiled by reference can not be determined, i.e., "a" + s1 can not be optimized compiler, only the dynamic assignment of new addresses after connection and assign s2 in the program run. Therefore, the above procedure will result to false

Compile OK

String s0 = "ab"; 
final String s1 = "b"; 
String s2 = "a" + s1;  
System.out.println((s0 == s2)); //result = true

Analysis: and [6] The only difference is the addition of a string s1 final modification, for the final modification of the variable, which is interpreted as a copy of the local memory at compile-time constant values ​​to their constant pool or embedded to its bytecode stream. Therefore, in this case "a" + s1 and "a" + "b" effect is the same. Therefore, the above procedure the result is true.

Compile time can not be determined.

String s0 = "ab"; 
final String s1 = getS1(); 
String s2 = "a" + s1; 
System.out.println((s0 == s2)); //result = false 
private static String getS1() {  return "b";   }

Analysis: JVM for string reference s1, its value can not be determined at compile time and only after calling the method of running the program, and the method returns the value "a" to dynamically assign addresses to the connection and s2, so that the result of the above procedure It is false.

About String immutable design:

String is immutable class (note: primitive wrapper classes are immutable) typical representative, also Immutable typical application design patterns, after a variable String can not be changed once initialized, prohibit changes to an object's state, thereby increasing the shared object robustness, reduce errors object access, but also avoids the need to synchronize when multiple threads share.
Immutable mode to achieve mainly in the following two points:

  1. In addition to constructor should not have any other functions (at least any public function) modify any member variables.
  2. Any member variables to get the new value of the function should be the new value is stored in the new object, while keeping the original object is not modified.

String immutability led to a string variable cost of using a plus sign:

String s = “a” + "b” + "c”; 
String s1  =  "a"; 
String s2  =  "b"; 
String s3  =  "c"; 
String s4  =   s1  +  s2  +  s3;

Analysis: Creating variable s is equivalent to a String s = "abc"; the above example can be seen by the compiler has been optimized, here only creates an object. By the above example we can also know s4 can not be optimized at compile time, which is equivalent to object creation:

StringBuffer temp = new StringBuffer();
temp.append(s1).append(s2).append(s3);
String s = temp.toString();

By the above analysis results, is easy to deduce that the String may join operator (+) Analysis inefficient, shaped like this code:

public class Test { 
    public static void main(String args[]) { 
        String s = null; 
            for(int i = 0; i < 100; i++) { 
                s += "a"; 
            } 
    } 
}

Each do a + produces a StringBuffer object, and then append after the throw. Regenerating a StringBuffer object before reaching the next cycle, and then append a string, and so on until the end. If we direct use StringBuffer object to append, we can save N - 1 times creating and destroying objects of the time. Therefore, in the cycle for the application of a string to be connected, usually with StringBuffer or objects to append operation StringBulider

Guess you like

Origin www.cnblogs.com/zouwangblog/p/11141183.html