Fundamentals 32 min read

Comprehensive Guide to Java String: Basics, Usage, Source‑Code Analysis, and Interview Questions

This article provides an in‑depth tutorial on Java's String class, covering primitive data types, official documentation, common usage examples, detailed source‑code walkthrough of constructors and key methods, as well as typical interview questions and performance considerations for backend development.

Full-Stack Internet Architecture
Full-Stack Internet Architecture
Full-Stack Internet Architecture
Comprehensive Guide to Java String: Basics, Usage, Source‑Code Analysis, and Interview Questions

Preface

Hello, I am Lao Tian. Today I share Java fundamentals about the String class, which is one of the most frequently used classes in backend development.

String Overview

We first review Java's eight primitive data types before introducing String.

Eight Primitive Types

byte: 8‑bit, range -128~127.

short: 16‑bit, range -32768~32767.

int: 32‑bit, range -2^31~2^31‑1.

long: 64‑bit, range -2^63~2^63‑1.

float: 32‑bit, range 3.4e‑45~1.4e38, suffix f/F.

double: 64‑bit, range 4.9e‑324~1.8e308, optional suffix d/D.

boolean: true or false.

char: 16‑bit Unicode character.

Beyond these, String is a special reference type representing a sequence of characters.

Official Documentation

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

String resides in the JDK under the rt.jar package as java.lang.String . Example declaration:

String str = "中国梦,我的梦";
String name = "zhangsan";

String Usage

Variable Definition

String is used extensively for defining variables, constants, and entity fields, e.g., a User class:

public class User {
    private Long id;
    private String userName;
    private String address;
    private String password;
    // ...
}

Common Method Demonstration

The following demo shows more than 20 String methods:

// Example code from the internet
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 ";
        System.out.println("r1: " + str1.length());
        System.out.println("r2 : " + str1.compareTo(str2));
        System.out.println("r3 : " + str1.compareTo(str3));
        System.out.println("r4 : " + str1.compareToIgnoreCase(str3));
        System.out.println("r5 : " + str1.indexOf("o"));
        System.out.println("r6 : " + str1.lastIndexOf("o"));
        System.out.println("r7 : " + str1.substring(0, 5) + str1.substring(6));
        System.out.println("r8 : " + str1.replace("o", "h"));
        System.out.println("r9 : " + str1.replaceAll("o", "h"));
        System.out.println("r10 : " + str1.replaceFirst("o", "h"));
        System.out.println("r11 : " + new StringBuffer(str1).reverse());
        System.out.println("r11' : " + new StringBuilder(str1).reverse());
        String[] temp = str1.split("\\ ");
        for (String s : temp) {
            System.out.println("r12 : " + s);
        }
        System.out.println("r13 : " + str1.toUpperCase());
        System.out.println("r14 : " + str1.toLowerCase());
        System.out.println("r15 : " + str4.trim());
        System.out.println("r16 : " + str1.contains("World"));
        System.out.println("r17 : " + str1.charAt(4));
        System.out.println("r18 : " + str1.endsWith("d"));
        System.out.println("r19 : " + str1.startsWith("H"));
        System.out.println("r20 : " + str1.startsWith("ll", 2));
        System.out.println("r21 : " + str1.concat("haha"));
        System.out.println("r22 : " + str1.equals(str2));
        System.out.println("r23 : " + str1.equalsIgnoreCase(str2));
        System.out.println("r24 : " + str1.isEmpty());
    }
}

Understanding these methods is essential for interviews.

Core Source‑Code Analysis

Note: JDK version 1.8+, slight differences exist in JDK 9.

Class Comment

/**
 * The {@code String} class represents character strings. All string literals
 * such as "abc" are implemented as instances of this class.
 * Strings are immutable; their values cannot be changed after creation.
 * Because they are immutable, they can be shared.
 * ... (additional Javadoc omitted for brevity)
 * @since JDK1.0
 */

Class Definition

public final class String implements java.io.Serializable, Comparable
, CharSequence {
    // ...
}

The class is final, implements Serializable, Comparable, and CharSequence.

Important Members

// The character array that stores the string content
private final char value[];
// Cached hash code, default 0
private int hash;
private static final long serialVersionUID = -6849794470754667710L;

Constructors

/** Creates an empty string. */
public String() {
    this.value = "".value;
}
/** Creates a new String that is a copy of the argument. */
public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}
/** Creates a new String from a char array. */
public String(char value[]) {
    this.value = Arrays.copyOf(value, value.length);
}
/** Creates a new String from a StringBuffer (thread‑safe). */
public String(StringBuffer buffer) {
    synchronized (buffer) {
        this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
    }
}
/** Creates a new String from a StringBuilder (non‑thread‑safe). */
public String(StringBuilder builder) {
    this.value = Arrays.copyOf(builder.getValue(), builder.length());
}

Key Methods Analysis

hashCode()

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char[] val = value;
        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

equals(Object)

public boolean equals(Object anObject) {
    if (this == anObject) return true;
    if (anObject instanceof String) {
        String anotherString = (String) anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            for (int i = 0; i < n; i++) {
                if (v1[i] != v2[i]) return false;
            }
            return true;
        }
    }
    return false;
}

substring(int)

public String substring(int beginIndex) {
    if (beginIndex < 0) throw new StringIndexOutOfBoundsException(beginIndex);
    int subLen = value.length - beginIndex;
    if (subLen < 0) throw new StringIndexOutOfBoundsException(subLen);
    return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}

intern()

public native String intern();

Returns a canonical representation from the string pool.

length()

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

isEmpty()

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

charAt(int)

public char charAt(int index) {
    if (index < 0 || index >= value.length) throw new StringIndexOutOfBoundsException(index);
    return value[index];
}

compareTo(String)

public int compareTo(String anotherString) {
    int len1 = value.length;
    int len2 = anotherString.value.length;
    int lim = Math.min(len1, len2);
    char v1[] = value;
    char v2[] = anotherString.value;
    for (int k = 0; k < lim; k++) {
        char c1 = v1[k];
        char c2 = v2[k];
        if (c1 != c2) return c1 - c2;
    }
    return len1 - len2;
}

startsWith / endsWith

public boolean startsWith(String prefix, int toffset) { /* implementation omitted */ }
public boolean startsWith(String prefix) { return startsWith(prefix, 0); }
public boolean endsWith(String suffix) { return startsWith(suffix, value.length - suffix.value.length); }

concat(String)

public String concat(String str) {
    int otherLen = str.length();
    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);
}

replace(char, char)

public String replace(char oldChar, char newChar) {
    if (oldChar != newChar) {
        int len = value.length;
        int i = -1;
        char[] val = value;
        while (++i < len) {
            if (val[i] == oldChar) break;
        }
        if (i < len) {
            char[] buf = new char[len];
            System.arraycopy(val, 0, buf, 0, i);
            while (i < len) {
                char c = val[i];
                buf[i] = (c == oldChar) ? newChar : c;
                i++;
            }
            return new String(buf, true);
        }
    }
    return this;
}

trim()

public String trim() {
    int len = value.length;
    int st = 0;
    char[] val = value;
    while ((st < len) && (val[st] <= ' ')) st++;
    while ((st < len) && (val[len - 1] <= ' ')) len--;
    return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}

valueOf(...)

public static String valueOf(boolean b) { return b ? "true" : "false"; }
public static String valueOf(char c) { return new String(new char[]{c}, true); }
public static String valueOf(int i) { return Integer.toString(i); }
// Integer.toString implementation omitted for brevity

split(String)

public String[] split(String regex) { return split(regex, 0); }
public String[] split(String regex, int limit) { /* uses regex engine */ }

String Interview Questions

How to compare strings?

Use equals() for content comparison; == checks reference equality.

How many objects does String str = new String("abc") create?

If "abc" is absent from the string pool, two objects are created (one in the pool, one on the heap). If it already exists, only the heap object is created.

Difference between String, StringBuilder, and StringBuffer

String: immutable, thread‑safe.

StringBuilder: mutable, not thread‑safe, higher performance for single‑threaded use.

StringBuffer: mutable, thread‑safe (synchronized), slightly slower.

String and the JVM

String literals are stored in the string pool (moved to the heap in JDK 7+). intern() returns the pooled instance.

Length limitation

String length is limited by int (max 2^31‑1) for runtime, but the constant‑pool index limits literals to 65534 characters at compile time.

Can String be used in a switch statement?

Supported since JDK 7.

Explain intern()

Before JDK 7, intern() creates a pool entry if absent; after JDK 7 it stores the heap reference directly in the pool.

For more details, see the referenced articles and source code.

JavaProgrammingJDKInterviewString()
Full-Stack Internet Architecture
Written by

Full-Stack Internet Architecture

Introducing full-stack Internet architecture technologies centered on Java

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.