preface

Hello everyone, I’m Tian, today I’m going to share with you the basics of Java String.

Needless to say, the String class is the most important class we use in back-end development, so it’s worth talking about.

The main contents of this paper are as follows:

Introduction of the String

Let’s talk about eight data types in Java, and then we’ll talk about strings.

Eight basic data types

Byte: stores a maximum of 255 bytes and ranges from -128 to 127.

Short: 16 bits, the maximum data storage is 65536, and the data range is between -32768 and 32767.

Int: 32-bit, the maximum data storage capacity is 2 ^ 32 minus 1, the data range is negative 2 ^ 31 to positive 2 ^ 31 minus 1.

Long: 64-bit. The maximum data storage capacity is 2 ^ 64 minus 1. The data range is from negative 2 ^ 63 to positive 2 ^ 63 minus 1.

Float: 32 bits. The value ranges from 3.4E-45 to 1.4e38. If the value is directly assigned, f or f must be added after the number.

Double: 64-bit, ranging from 4.9E-324 to 1.8e308. The value can be assigned with or without D.

Boolean: The value can be true or false.

Char: 16 bits, stores Unicode codes, and uses single quotes to assign values.

In addition to these eight datatypes (which have encapsulation equivalents, as I’m sure you know), there is another special type in Java: String, which literally means String.

String Official Introduction

The English version

Address: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html

Can’t you read it? No problem, we can borrow the translation tool, the browser comes with, more hope is you can understand the original English.

String exists in the rt.ar package in the JDK directory we installed. The full path is named java.lang.string. In our Java code, String is used to represent a String, as in:

String STR = "Chinese dream, my dream "; String name = "zhangsan";Copy the code

That’s all we need to know for now.

String to use

Define the type of

In everyday development, strings are used a lot, especially to define the types of variables and constants, and you’ll see them almost everywhere you code.

For example, User information is represented by the entity class User.

public class User{
    private Long id;
    private String userName;
    private String address;
    privateString password; . }Copy the code

Common method demonstration

The String class has more than 20 methods. Here’s an example of how to use them (most of them are shown here, but you can try the rest).

// Example code, from the network
public class StringDemo {
    public static void main(String[] args) throws Exception {
        String str1 = "Hello World";
        String str2 = "Hello World";
        String str3 = "hello world";
        String str4 = " hello world ";
        // Returns the length of the string
        System.out.println("r1: " + str1.length());
        CompareTo (returns int),0 equal, complex less than, positive greater than
        System.out.println("r2 : " + str1.compareTo(str2));
        CompareTo (returns int),0 equal, complex less than, positive greater than
        System.out.println("r3 : " + str1.compareTo(str3));
        // compareToIgnoreCase compareToIgnoreCase, ignoring case. 0 is equal, complex numbers are less than, positive numbers are greater than
        System.out.println("r4 : " + str1.compareToIgnoreCase(str3));
        // String search indexOf, returns the location of the first found, returns -1 if not found. Starting from 0
        System.out.println("r5 : " + str1.indexOf("o"));
        // Find the position lastIndexOf the last occurrence of the string
        System.out.println("r6 : " + str1.lastIndexOf("o"));
        // Delete a character from the string, substring(a, b) starting from 0
        // Returns a string between the specified start (inclusive) and end (exclusive) positions
        System.out.println("r7 : " + str1.substring(0.5) + str1.substring(6));

        // String replacement, replace all
        System.out.println("r8 : " + str1.replace("o"."h"));
        // String replacement, replace all
        System.out.println("r9 : " + str1.replaceAll("o"."h"));
        // String substitution, replace the first one
        System.out.println("r10 : " + str1.replaceFirst("o"."h"));
        // String reversal
        System.out.println("r11 : " + new StringBuffer(str1).reverse());
        // String reversal
        System.out.println("r11’: " + new StringBuilder(str1).reverse());
        // String split
        String[] temp = str1.split("\\ ");
        for (String str : temp) {
            System.out.println("r12 : " + str);
        }
        // Uppercase the string
        System.out.println("r13 : " + str1.toUpperCase());
        // Change the string to lowercase
        System.out.println("r14 : " + str1.toLowerCase());
        // Remove the leading and trailing Spaces
        System.out.println("r15 : " + str4.trim());
        // Case sensitive
        System.out.println("r16 : " + str1.contains("World"));
        // Returns the specified position character
        System.out.println("r17 : " + str1.charAt(4));
        // Tests whether the string ends with the specified suffix
        System.out.println("r18 : " + str1.endsWith("d"));
        // Tests whether the string starts with the specified prefix
        System.out.println("r19 : " + str1.startsWith("H"));
        // Tests whether substrings of this string starting with the specified index start with the specified prefix
        System.out.println("r20 : " + str1.startsWith("ll".2));
        // Concatenates the specified string to the end of the string. That's the same thing as using +
        System.out.println("r21 : " + str1.concat("haha"));
        // Compares whether the contents of the strings are the same
        System.out.println("r22 : " + str1.equals(str2));
        // Like equals, ignore case
        System.out.println("r23 : " + str1.equalsIgnoreCase(str2));
        // Check if it is an empty string
        System.out.println("r24: "+ str1.isEmpty()); }}Copy the code

That’s pretty much what we’ve done in development, but if you’re just good at it, you’ll probably still fail in an interview. Therefore, learning knowledge, can not stay in the use of the level, need a deeper level of learning.

Now let’s go to the deep learning String, I hope you take an ordinary heart to learn, do not be afraid of what, the lantern is a piece of paper, broken is not valuable.

String core source code analysis

Note: THE JDK version is 1.8+, as the JDK9 version has slight differences from the older version.

String class source comments

/**
 * The {@code String} class represents character strings. All
 * string literals in Java programs, such as {@codeImplemented as instances of this class. "ABC "}, are * implemented as instances of this class. All string constants in Java programming. * For example, "ABC" is an instance of the String class * <p> * Strings are constant; Their values cannot be changed after they * are created. * Strings are constants. Once they are created, their values cannot be changed. * String Buffers support mutable strings. * String Buffers support mutable strings. * Because String objects are immutable they can be shared. For example: * Because strings are immutable, but they can be shared. * <blockquote><pre> * String STR = "ABC "; * </pre></blockquote><p> * is equivalent to: * <blockquote><pre> * char data[] = {'a', 'b', 'c'}; * String str = new String(data); * </pre></blockquote><p> * Here are some more examples of how strings can be used: * String Use Case * system.out.println (" ABC "); * String cde = "cde"; * System.out.println("abc" + cde); * String c = "ABC ". Substring (2,3); * String d = cde.substring(1, 2); * <p> * The class {@code String} includes methods for examining
 * individual characters of the sequence, for comparing strings, for
 * searching strings, for extracting substrings, and for creating a
 * copy of a string with all characters translated to uppercase or to
 * lowercase. Case mapping is based on the Unicode Standard version
 * specified by the {@linkJava.lang.Character Character} class. * This String class contains methods for evaluating a single Character sequence, such as String comparison, finding a String, extracting a String, and making a case-sensitive copy of a String. * Case maps to the standard version of Unicode based on the Character set supported by the Character class. * <p> * The Java language provides special support for the string * concatenation operator (&nbsp; +&nbsp;) , and for conversion of * other objects to strings. * The Java language provides special support for strings, such as: String concatenation is implemented * through the {String concatenation is implemented for other classes * String concatenation is implemented * through the {@code StringBuilder}(or {@code StringBuffer})
 * class and its {@codeString conversions are implemented through The StringBuilder or StringBuffer append() method * through the method * {@code toString}, defined by {@codeInherited by all classes in Java. Inherited by all classes in Java. Inherited by all classes in Java information on * string concatenation and conversion, see Gosling, Joy, and Steele, * <i>The Java Language Specification</i>. * * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor * or method in this class will cause a {@linkThrown to be * thrown. * Unless otherwise specified, throw A null to A String constructor or to A thrown method.@code String} represents a string in the UTF-16 format
 * in which <em>supplementary characters</em> are represented by <em>surrogate
 * pairs</em> (see the section <a href="Character.html#unicode">Unicode
 * Character Representations</a> in the {@codeCharacter} class for * more information). * A String object represents a utF-16 encoding syntax consisting of a String * Index values refer to {@code char} code units, so a supplementary
 * character uses two positions in a {@code String}.
 * <p>The {@code String} class provides methods for dealing with
 * Unicode code points (i.e., characters), in addition to those for
 * dealing with Unicode code units (i.e., {@codeChar} values). * Index values point to character code units, so a character uses two positions in a String, and the String class provides some method areas to handle individual Unicode encodings, in addition to those that handle Unicode code units. *@sinceJDK1.0 * /
Copy the code

That’s the whole section of the String class annotation, and the rest is the author, the related classes, the related methods, and which version of the JDK is available from.

The String class definition

public final class String
    implements java.io.Serializable.Comparable<String>, CharSequence {... }Copy the code

The class diagram

The String class is final to indicate that String cannot be inherited. Let’s talk about how String implements three interfaces:

  • Implement Serializable, which can be serialized

  • Implement Comparable, which can be used to compare sizes (ASCII codes of individual characters in order)

  • Implement CharSequence, which represents an ordered sequence of characters (because String is essentially a char array)

A brief introduction to Final

Modifier class: the class cannot be inherited, that is, the String class cannot be inherited

Modifier methods: Lock a method to any inherited class to modify its meaning

Modifier traversal: Cannot be changed after initialization

Important members

 /** The value is used for character storage. */
// To store the contents of a String
private final char value[];
// Stores string hash values, default is 0
private int hash; // Default to 0
// Implement serialized identity
private static final long serialVersionUID = -6849794470754667710L;
Copy the code

Char value[] is final, indicating that the value[] array is immutable.

A constructor

/**
 * Initializes a newly created {@codeString} object so that it represents * an empty character sequence. Note that use of this constructor is * unnecessary Since Strings are immutable. * Initializes a newly created String object, period representing an empty sequence of Strings. * Note: the use of this constructor is unnecessary because strings are immutable */
public String(a) {
        this.value = "".value;
}
Copy the code

The no-argument constructor assigns the value of an empty string to the current value.

 /**
  * Initializes a newly created {@code String} object so that it represents
  * the same sequence of characters as the argument; in other words, the
  * newly created string is a copy of the argument string. Unless an
  * explicit copy of {@codeOriginal} is needed, use of this constructor is * unnecessary since Strings are immutable. Periods represent sequences of strings that are the same as parameters. * In other words: The newly created string is a self-rough copy of the arguments. * Unless a display copy of Original is required, there is no need to use this constructor * because strings are immutable *@param  original
  *         A {@code String}
  */
 public String(String original) {
     this.value = original.value;
     this.hash = original.hash;
 }
// case: String STR =new String(" ABC ");
Copy the code

Assign original’s value to the current value and Original’s hash to the current hash.

/**
 * Allocates a new {@codeString} so that it represents the sequence of * characters currently contained in the character array argument. The * contents of the character array are copied; Subsequent modification of * the character array does not affect the newly created string. * Allocating a new {@codeString} so that it represents the characters currently contained in the character array parameter. This * copies the contents of the character array; Subsequent changes to the character array do not affect the newly created string. *@param  value
 *         The initial value of the string
 */
public String(char value[]) {
    // Copy the char array into the value array
    this.value = Arrays.copyOf(value, value.length);
}
// copyOf methods in the Arrays class
public static char[] copyOf(char[] original, int newLength) {
    // Create a new char array
    char[] copy = new char[newLength];
    // Copy the contents of the Original array into the new char array
    System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
    // Returns the newly created char array
    return copy;
}
Copy the code

Use the copyOf method of the Arrays class to create a new CHAR array that contains the contents of Original.

The newly created char array is then assigned to the current vlaue.

public String(StringBuffer buffer) {
   synchronized(buffer) {
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); }}Copy the code

Because StringBuffer is thread-safe, a synchronization lock is added to keep it thread-safe.

public String(StringBuilder builder) {
        this.value = Arrays.copyOf(builder.getValue(), builder.length());
}
Copy the code

StringBuilder is not thread-safe, so there is no thread-safe processing here, and everything else is the same.

Note: A lot of times we don’t do this because StringBuilder and StringBuffer have toString methods. If thread safety is not an issue, StringBuilder is preferred

So that’s all I’m going to talk about here, and the rest is complicated and I don’t really use it, so that’s all you need to know. If you’re interested in something else, do your own research.

Analysis of common methods

We’ve already demonstrated most of String’s methods in the previous use cases, so let’s pick out a few of the more important ones for in-depth analysis.

HashCode methods

The hashCode() method is defined in the Object class, and String overrides it.

public int hashCode(a) {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;
            // Hash algorithm, s[0]*31^(n-1) + s[1]*31^(n-2) +... + s[n-1]
            // Use the {@codeint} algorithm, where {@codes[I]} is the first character of the string < I > I 
      ,
            //{@code n} is a string, {@code^} is an exponential operation.
            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
}

Copy the code

A concrete implementation of hashCode. Since every object in the Java architecture can be converted to a String, they should all be implemented using this hash

Next, we look at equals();

The equals () method

The equals() method is also defined in Object, overridden by String.

Public Boolean equals(Object anObject) {if (this == anObject) {return true; If (anObject instanceof String) {String anotherString = (String)anObject; int n = value.length; / / is the same length of the if (n = = anotherString. Value. Length) {char v1 [] = value; char v2[] = anotherString.value; int i = 0; While (n--! If (v1[I]! = 0) {// if (v1[I]! = v2[i]) return false; i++; } return true; } } return false; }Copy the code

Add: == comparison

== Compares base data types, values == compares reference data types, address valuesCopy the code

The substring () method

The substring method is also used quite a bit at work, simply to intercept a string.

public String substring(int beginIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } int subLen = value.length - beginIndex; if (subLen < 0) { throw new StringIndexOutOfBoundsException(subLen); } // If beginIndex==0, return the current object, otherwise this is a new object of new, in fact many functions in String do this return (beginIndex ==0)? this : new String(value, beginIndex, subLen); }Copy the code

Intern () method

Intern () is a native modified method, indicating that the method is a local method.

/*
 * When the intern method is invoked, if the pool already contains a
 * string equal to this {@code String} object as determined by
 * the {@link #equals(Object)} method, then the string from the pool is
 * returned. Otherwise, this {@code String} object is added to the
 * pool and a reference to this {@code String} object is returned.
 */
public native String intern();

Copy the code

The method comment will write, which means that when a method is called, if the constant pool has the value of the current String, it will return that value, and if it doesn’t, it will add it and return a reference to that value.

Case as follows

public class StringDemo { public static void main(String[] args) throws Exception { String str1 = "a"; String str2 = "b"; String str3 = "ab"; String str4 = str1 + str2; String str5 = new String("ab"); System.out.println(str5 == str3); Println (str5.intern() == str3); // Intern () == String (); // Intern () == String (); // Reference system.out.println (str5.intern() == str4); // The variables are added to a new value, so str4 references a new system.out.println (str4 == str3); // The variables are added to a new value, so str4 references a new}}Copy the code

The results

false
true
false
false

Copy the code

The length () method

Get the string length, actually get the character array length, the source code is very simple, there is nothing to say.

public int length() {
    return value.length;
}

Copy the code

IsEmpty () method

To determine whether the string is empty, in fact, is looking at whether the complex character array length is 0, the source code is also very simple, nothing to say.

public boolean isEmpty() {
    return value.length == 0;
}

Copy the code

The charAt (int index) method

Gets characters based on index parameters.

public char charAt(int index) {
    // If the index is less than 0 or greater than the character array length, an out-of-bounds exception is thrown
    if ((index < 0) || (index >= value.length)) {
        throw new StringIndexOutOfBoundsException(index);
    }
    // Returns an array of positional characters
    return value[index];
}

Copy the code

GetBytes () method

Gets a byte array of strings, decoding the string to a byte array according to the system default character encoding.

public byte[] getBytes() {
    return StringCoding.encode(value, 0, value.length);
}

Copy the code

CompareTo () method

This method is cleverly written, starting with 0 to determine the character size. If two objects are equal in the number of characters they can compare, it returns its length minus the length of the object being compared. If two strings are equal in length, it returns 0.

public int compareTo(String anotherString) {
    // Own object string length len1
    int len1 = value.length;
    // The object being compared is a string of len2 characters
    int len2 = anotherString.value.length;
    // Take the minimum of two string lengths, lim
    int lim = Math.min(len1, len2);
    char v1[] = value;
    char v2[] = anotherString.value;
 
    int k = 0;
    // From the first character of value to the minimum length lim, if the characters are not equal,
    // Return itself (unequal character of object - unequal character of object being compared)
    while (k < lim) {
        char c1 = v1[k];
        char c2 = v2[k];
        if(c1 ! = c2) {return c1 - c2;
        }
        k++;
    }
    // Return (length of itself - length of the object being compared)
    return len1 - len2;
}

Copy the code

StartsWith () method

public boolean startsWith(String prefix, int toffset) {
    char ta[] = value;
    int to = toffset;
    char pa[] = prefix.value;
    int po = 0;
    int pc = prefix.value.length;
    // Note: toffset might be near -1>>>1.
    // If the start address is less than 0 or (the start address + the length of the compared object) is greater than the length of its own object, false is returned
    if ((toffset < 0) || (toffset > value.length - pc)) {
        return false;
    }
    // Start at the end of the object being compared
    while (--pc >= 0) {
        if(ta[to++] ! = pa[po++]) {return false; }}return true;
}
 
public boolean startsWith(String prefix) {
    return startsWith(prefix, 0);
}
 
public boolean endsWith(String suffix) {
    return startsWith(suffix, value.length - suffix.value.length);
}
Copy the code

Start comparison and end comparison are commonly used to compare, for example, to determine whether a string is HTTP, or to determine whether a file is mp3.

Concat () method

public String concat(String str) {
    int otherLen = str.length();
    // If the added string is empty, return the object itself
    if (otherLen == 0) {
        return this;
    }
    int len = value.length;
    char buf[] = Arrays.copyOf(value, len + otherLen);
    str.getChars(buf, len);
    return new String(buf, true);
}
Copy the code

The concat method is also commonly used to determine whether the added string is empty to create a new object.

The replace () method

public String replace(char oldChar, char newChar) {
    // Compare the old and new values first
    if(oldChar ! = newChar) {int len = value.length;
        int i = -1;
        char[] val = value; 
 
        // Find where the old value started
        while (++i < len) {
            if (val[i] == oldChar) {
                break; }}// Start at that position and end with the new value instead of the old value
        if (i < len) {
            char buf[] = new char[len];
            for (int j = 0; j < i; j++) {
                buf[j] = val[j];
            }
            while (i < len) {
                char c = val[i];
                buf[i] = (c == oldChar) ? newChar : c;
                i++;
            }
            return new String(buf, true); }}return this;
}
Copy the code

This method also has some tricks, such as finding out where the old values appear in the first place, which saves some comparison time. The replace(String oldStr,String newStr) method is determined by regular expressions.

The trim () method

public String trim(a) {
    int len = value.length;
    int st = 0;
    char[] val = value;    /* avoid getfield opcode */
 
    // Find the position without Spaces at the beginning of the string
    while ((st < len) && (val[st] <= ' ')) {
        st++;
    }
    // Find the position without Spaces at the end of the string
    while ((st < len) && (val[len - 1] < =' ')) {
        len--;
    }
    // Returns the string itself if there is no space before or after it
    return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}
Copy the code

The trim method simply deletes the whitespace from the string.

The valueOf () method

public static String valueOf(boolean b) {
   // return "true" if b is true, otherwise return "false"
   return b ? "true" : "false";
}
public static String valueOf(char c) {
    // Create the data[] array and add c to it
    char data[] = {c};        
     // Create a new String and return it
    return new String(data, true); 
}
public static String valueOf(int i) {
    // Call the toString() method of the Integer object and return it
    return Integer.toString(i);  
}
// toString(I) in the Integer class
public static String toString(int i) {
    // Specifies whether the value is Integer
    if (i == Integer.MIN_VALUE)
       return "2147483648";
    // How many bits does this I have
    int size = (i < 0)? stringSize(-i) +1 : stringSize(i);
    // Create a char array
    char[] buf = new char[size];
    // Delimit the contents of the I method into an array
    getChars(i, size, buf);
    // Return a String
    return new String(buf, true);
}
Copy the code

The split () method

public String[] split(String regex) {
    return split(regex, 0);
}
// Regular expressions are used
public String[] split(String regex, int limit) {
      //....
    // The source code is a bit too much, anyway, inside the use of regular expressions, for segmentation
    }
Copy the code

The split() method splits a string into an array of strings, returning an array of strings that does not include the regex itself. The optional “limit” is an integer, which defaults to 0 in the first method, allowing you to specify the maximum number of array elements to return.

Common method source analysis so much, let’s review the use of scenarios, especially in the interview.

String common interview questions

How do strings compare the same?

There are usually two ways to compare objects in Java:

  • = =

  • The equals method

Note the difference between == used for comparison of primitive data types and comparison of reference types.

== Compares basic data types, and compares values

== compares reference data types, and addresses

In addition, String overrides equals, so we’ll still use equals to compare strings. The equals method of strings contains a check for == (see previous source code analysis).

case

public class StringDemo {
   public static void main(String[] args) {
     String st1 = "abc";
     String st2 = "abc"; System.out.println(st1 == st2); System.out.println(st1.equals(st2)); }}Copy the code

The output

true
true

Copy the code

String str=new String(“abc”); How many objects does this line of code create?

Take a look at this code:

String str1 = "abc"; String str2 = new String(" ABC "); / / on the heapCopy the code

For this code, I’ve created several objects, how many online answers are there, one, two, and three. So let’s talk about how many?

First, we need to be clear; Either str1 or str2, they’re strings, they’re not objects, and normally we might call them str2 objects, just to make it easier to understand, str2 and str1 are not objects, per se.

Second, String STR =” ABC “; The string “ABC” is stored in the string constant pool with only one copy, and the assignment operation is equivalent to creating zero or one object. If “ABC” already exists in the constant pool, the object is not created and the reference is assigned to str1; If there is no “ABC” in the constant pool, create an object and assign the reference to str1.

So, new String(” ABC “); What is the form of?

The answer is one or two.

When the JVM encounters the above code, it first retrieves the constant pool for the presence of “ABC”, and if it does not, it creates the string in the constant pool. The new operation then creates a String containing “ABC” in heap memory, and assigns the reference to str2. This process creates two objects.

Of course, if the constant pool is retrieved and the corresponding String already exists, only a new String is created in the heap, and only 1 object is created.

Finally, if you ask String alone STR =new String(” ABC “); Create several objects, remember: constant pool exists “ABC”, yes, create an object; There is no creating two objects.

StringBuilder and StringBuffer

Thread safety

Objects in strings are immutable, which means they are considered constants, thread-safe. AbstractStringBuilder AbstractStringBuilder is a common parent of StringBuilder and StringBuffer. AbstractStringBuilder defines some basic string operations, such as expandCapacity, Append, insert, indexOf and other public methods. StringBuffer places synchronization locks on methods or on invoked methods, so it is thread-safe. StringBuilder does not lock methods synchronously-so it is not thread-safe.

performance

Each time a String type is changed, a new String is generated and a pointer is pointed to the new String. A StringBuffer operates on the StringBuffer object itself each time, rather than generating new objects and changing object references. Using StringBuilder in the same situation yields only 10% to 15% performance improvement over using StringBuffer, but at the risk of multithreading insecurity.

Summary of the use of the three:

  • To manipulate small amounts of data, String is recommended

  • A StringBuilder is recommended for single-thread manipulation of large amounts of data in a string buffer

  • A StringBuffer is recommended for multi-threaded manipulation of large amounts of data in a StringBuffer

What does String have to do with the JVM?

There are two common ways to create a String: new String() and direct assignment. The direct assignment method first checks the String constant pool to see if the value already exists, and if so, refers to the reference address directly to the value. Otherwise, the String is created in the constant pool and then refers to the value. The new String() method always creates a String object on the heap, and then queries the constant pool to see if the String already exists. If not, the String is created in the constant pool, and then references the value to the String.

Constant pools in the JVM

Literals – text strings, i.e. public String s = “ABC” in our example; The “ABC”.

Member variables modified with final include static variables, instance variables, and local variables.

Take a look at the following code:

String s1 = new String("Java");
String s2 = s1.intern();
String s3 = "Java";
System.out.println(s1 == s2); // false
System.out.println(s2 == s3); // true
Copy the code

They are stored in the JVM as shown below:

Note: Since JDK 1.7, the immortal generation has been replaced with a meta-space, moving the string constant pool from the method area to the Java heap.

In addition, the compiler also makes some optimizations for the String String, such as the following code:

String s1 = "Ja" + "va";
String s2 = "Java";
System.out.println(s1 == s2);

Copy the code

S1 concatenates multiple strings, but the comparison result is true. Using the decompiler, we see the following result:

Compiled from "StringExample.java"
public class com.lagou.interview.StringExample {
  public com.lagou.interview.StringExample();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
    LineNumberTable:
      line 3: 0
  public static void main(java.lang.String[]);
    Code:
       0: ldc           #2                  // String Java
       2: astore_1
       3: ldc           #2                  // String Java
       5: astore_2
       6: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
       9: aload_1
      10: aload_2
      11: if_acmpne     18
      14: iconst_1
      15: goto          19
      18: iconst_0
      19: invokevirtual #4                  // Method java/io/PrintStream.println:(Z)V
      22: return
    LineNumberTable:
      line 5: 0
      line 6: 3
      line 7: 6
      line 8: 22
}

Copy the code

As you can see from compiling code #2, the code “Ja”+”va” is compiled directly to “Java”, so s1==s2 is true, which is the result of the compiler’s string optimization.

How do I determine how many characters are the same in two strings

  • Convert a string to an array

  • A HashMap method

  • Strings are directly compared

  • Regular expression

  • HashSet method

Does String have a length limit? How much is? Why is that?

Here is a look at the length method source:

private final char value[];
public int length(a) {
        return value.length;
}
Copy the code

The length() method returns an int, so you can see that the length of a String cannot exceed integer.max_value.

A: The contents of a String are stored by an array char[]. Since the length and index of the array are integers, and the String method length() returns an int, The maximum size of an Integer array is 2^ 31-1. Since the array starts at 0, the maximum size of an Integer array is about 4GB.

But by looking through the Java Virtual Machine manual for class file format definition and constant pool for String structure definition we can know for index definition u2, is unsigned for 2 bytes, 2 bytes can represent the maximum range is 2^ 16-1 = 65535.

But since the JVM requires 1 byte to represent the closing instruction, the range is 65534. Anything beyond this range will cause an error at compile time, but the range for run-time concatenation or assignment is within the maximum range of the integer.

Can string objects be used in switch expressions?

As of JDK7, we can use strings in switch conditional expressions, which is not possible prior to version 7.

switch (str.toLowerCase()) {
      case "tian":
           value = 1;
           break;
      case "jiang":
           value = 2;
           break;
}
Copy the code

Talk about the intern method in String

In previous versions of JDK7, this method checks to see if the constant already exists in the constant pool. If it already exists, it returns the constant’s address in the constant pool. If it doesn’t, it creates one in the constant pool and returns its address.

But in JDK7 and later, the constant pool has been moved from the PERm area to the heap area. When a constant does not exist in the constant pool, the object is not directly created in the constant pool. Instead, the reference to the object in the heap is stored in the constant pool, reducing memory overhead.

The following case

public class InternTest {
  
  public static void main(String[] args) {
    String str1 = new String("hello") + new String("world");
    str1.intern();
    String str2 = "helloworld";
    System.out.println(str1 == str2);//true
    System.out.println(str1.intern() == str2);//true}}Copy the code

Well, that’s it for the Stirng class, and feel free to talk to me about some more technical questions.

String s = new String(“111”) how many objects will be created?

reference

prren.cn/vWv68 prren.cn/7ICgG dsblb.cn/ku78V Wang Lei “Java source code analysis 34 lectures”