Common Java Core API Classes: Wrapper Types, String, StringBuffer and StringBuilder

Primitive Type Wrapper Classes

Wraper classes serve two core purposes in Java:

  1. Provide object-oriented representations of primitive data types, allowing primitives to be used in collection frameworks that only accept objects.
  2. Encapsulate primitive-specific metadata (such as maximum/minimum values) and utility methods for type conversion, comparison, and formatting.

The 8 primitive types and their corresponding wrapper classes are:

Primitive Type Wrapper Class
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

Below examples use java.lang.Integer to demonstrate common wrapper class operations:

package com.example.coreutil.wrapper;

public class IntegerUsageSample {
    public static void main(String[] args) {
        // Create Integer instances via constructor
        Integer intWrap1 = new Integer(15);
        System.out.println(intWrap1); // Output 15
        Integer intWrap2 = new Integer("9");
        System.out.println(intWrap2); // Output 9

        // Create Integer instances via valueOf static method
        Integer intWrap3 = Integer.valueOf(15);
        System.out.println(intWrap3); // Output 15
        Integer intWrap4 = Integer.valueOf("9");
        System.out.println(intWrap4); // Output 9

        // Instance methods for wrapper objects
        int compareResult = intWrap1.compareTo(intWrap2);
        System.out.println(compareResult); // Output 1 (15 > 9)
        System.out.println(intWrap1 == intWrap2); // Compare addresses: false
        System.out.println(intWrap1.equals(intWrap2)); // Compare values: false
        int primitiveVal = intWrap1.intValue();
        System.out.println(primitiveVal); // Extract primitive value: 15

        // Static utility methods
        int staticCompareRes = Integer.compare(15, 9);
        System.out.println(staticCompareRes); // Output 1
        String hexVal = Integer.toHexString(14529);
        System.out.println(hexVal); // Output hex representation of 14529
        System.out.println(Integer.max(15,9)); // Output 15

        int parsedInt = Integer.parseInt("25"); // Convert numeric string to int primitive
    }
}

Autoboxing and Unboxing

Autoboxing

Autoboxing refers to the automatic conversion of primitive values to their corresponding wrapper type enstances, without explicit constructor or valueOf calls. The underlying implementation implicitly invokes the valueOf() method of the wrapper class.

package com.example.coreutil.wrapper;

public class BoxingSample {
    public static void main(String[] args) {
        int primitiveInt = 15;
        Integer wrappedInt = primitiveInt; // Autoboxing, equivalent to Integer.valueOf(15)
    }
}
Integer Cache Mechanism

The Integer.valueOf() method implements a cache for values in the range [-128, 127] by default. When autoboxing values within this range, no new Integer instance is created; instead, a pre-created instance from the cache array is returned. Values outside this range will always create new Integer instances.

package com.example.coreutil.wrapper;

public class IntegerCacheSample {
    public static void main(String[] args) {
        Integer wrapA = 22;
        Integer wrapB = 22;
        System.out.println(wrapA == wrapB); // true, same cache instance
        System.out.println(wrapA.equals(wrapB)); // true, same value

        Integer wrapC = Integer.valueOf(130);
        Integer wrapD = Integer.valueOf(130);
        System.out.println(wrapC == wrapD); // false, new instances for values outside cache range
        System.out.println(wrapC.equals(wrapD)); // true, same value
    }
}

Unboxing

Unboxing is the reverse operation of autoboxing: automatic conversion of wrapper type instances to their corresponding primitive values. The underlying implementation implicitly invokes the primitive value extraction method (e.g., intValue() for Integer).

package com.example.coreutil.wrapper;

public class UnboxingSample {
    public static void main(String[] args) {
        int primitiveInt = 15;
        Integer wrappedInt = primitiveInt; // Autoboxing

        int newPrimitive = wrappedInt; // Unboxing, equivalent to wrappedInt.intValue()
    }
}

String Class

Core Characteristics

java.lang.String represents immutable character sequences in Java. All values enclosed in double quotes are instances of the String class. Once a String instance is created, its value cannot be modified.

The underlying storage of String content is a final modified character array, which is initialized only during instance construction via the constructor: private final char value[];. All concatenation or modification operations on String objects will create new String instances, rather than modifying the original object.

package com.example.coreutil.string;

public class StringImmutabilitySample {
    public static void main(String[] args) {
        String str = "xyz";
        str += "123";
        str += "456";
        str += "789";
        System.out.println(str); // Output xyz123456789, 3 new String instances created during concatenation
    }
}

Instance Creation Patterns

There are two common ways to create String instances, with different memory allocation behaviors:

  1. Literal creation: String str1 = "test"; When creating a string literal, the JVM first checks the string constant pool. If a string with the same content already exists, the reference to the existing instance is returned directly. If not, a new instance is created in the constant pool and its reference is returned.
  2. Constructor creation: String str2 = new String("test"); Regardless of whether the same content exists in the constant pool, a new String instance is always created in the heap memory.
package com.example.coreutil.string;

public class StringCreationSample {
    public static void main(String[] args) {
        String str1 = "test123";
        String str2 = "test123";
        System.out.println(str1 == str2); // true, same instance from constant pool
        System.out.println(str1.equals(str2)); // true, same value

        str1 += "suffix";
        System.out.println(str1); // Output test123suffix, new instance created

        String str3 = new String("test123");
        String str4 = new String("test123");
        System.out.println(str3 == str4); // false, two separate heap instances
        System.out.println(str3.equals(str4)); // true, same value
    }
}

Common Constructors

  • String(): Creates an empty string instance
  • String(String content): Creates a string with the specified content
  • String(byte[] byteArr): Creates a string by decoding the specified byte array using the default platform encoding
  • String(char[] charArr): Creates a string by copying the content of the specified character array
package com.example.coreutil.string;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;

public class StringConstructorSample {
    public static void main(String[] args) {
        String emptyStr = new String();
        String contentStr = new String("testContent");

        String testStr = "hello世界";
        // Encode string to byte array
        byte[] byteArr = testStr.getBytes(StandardCharsets.UTF_8);
        System.out.println(Arrays.toString(byteArr));

        // Decode byte array back to string
        String decodedStr = new String(byteArr, StandardCharsets.UTF_8);
        System.out.println(decodedStr); // Output hello世界

        String charSource = "xzyw";
        char[] charArr = charSource.toCharArray();
        Arrays.sort(charArr);
        String sortedStr = new String(charArr);
        System.out.println(sortedStr); // Output wxyz
    }
}

Common Member Methods

Judgment Methods

Method Signature Function
boolean equals(Object obj) Compares if the string content is equal to the target object
boolean equalsIgnoreCase(String str) Compares content equality ignoring case
boolean contains(String substr) Checks if the string contains the specified continuous substring
boolean isEmpty() Checks if the string is an empty string ("")
boolean startsWith(String prefix) Checks if the string starts with the specified prefix
boolean endsWith(String suffix) Checks if the string ends with the specified suffix
package com.example.coreutil.string;

public class StringJudgeMethodsSample {
    public static void main(String[] args) {
        String testStr = "wxyz";
        String emptyStr = "";

        System.out.println(testStr.equals("wxyz")); // true
        System.out.println(testStr.equalsIgnoreCase("WxYz")); // true

        System.out.println(testStr.contains("wx")); // true
        System.out.println(testStr.contains("wy")); // false

        System.out.println(testStr.isEmpty()); // false
        System.out.println(emptyStr.isEmpty()); // true

        System.out.println(testStr.startsWith("wx")); // true
        System.out.println(testStr.endsWith("yz")); // true
    }
}

Accessor Methods

Method Signature Function
int length() Returns the length of the string
char charAt(int index) Returns the character at the specified index position
int indexOf(String substr) Returns the index of the first occurrence of the specified substring, returns -1 if not found
int indexOf(String substr, int fromIndex) Starts searching for the substring from the specified index
int lastIndexOf(String substr) Returns the index of the last occurrence of the specified substring
String substring(int start) Returns a substring starting from the specified index to the end of the string
String substring(int start, int end) Returns a substring from the start index (inclusive) to the end index (exclusive)
package com.example.coreutil.string;

public class StringAccessMethodsSample {
    public static void main(String[] args) {
        String testStr = "xycdcfe";
        // Indices: 0:x,1:y,2:c,3:d,4:c,5:f,6:e

        System.out.println(testStr.length()); // Output 7
        System.out.println(testStr.charAt(1)); // Output y
        System.out.println(testStr.indexOf("c")); // Output 2
        System.out.println(testStr.indexOf("c", 3)); // Output 4, search from index 3
        System.out.println(testStr.lastIndexOf("c")); // Output 4
        System.out.println(testStr.lastIndexOf("c", 3)); // Output 2, search backwards from index 3

        System.out.println(testStr.substring(2)); // Output cdcfe
        System.out.println(testStr.substring(0, 4)); // Output xycd
    }
}

Conversion Methods

Method Signature Function
byte[] getBytes() Encodes the string into a byte array using the default encoding
char[] toCharArray() Converts the string to a character array
static String valueOf(Object obj) Converts any type to a string, safely handles null values
String toLowerCase() Converts all characters in the string to lowercase
String toUpperCase() Converts all characters in the string to uppercase
String concat(String str) Concatenates the specified string to the end of the current string
String[] split(String delimiter) Splits the string into an array using the specified delimiter
package com.example.coreutil.string;

import java.util.Arrays;

public class StringConvertMethodsSample {
    public static void main(String[] args) {
        Long nullLong = null;
        String nullStr = String.valueOf(nullLong);
        System.out.println(nullStr); // Output "null", no NullPointerException

        char[] charArr = {'p','q','r','s'};
        String charToStr = String.valueOf(charArr);
        System.out.println(charToStr); // Output pqrs

        String caseStr = "pqrsTUV测试";
        System.out.println(caseStr.toLowerCase()); // Output pqrstuv测试
        System.out.println(caseStr.toUpperCase()); // Output PQRSTUV测试

        String concatStr = caseStr.concat("suffix");
        System.out.println(concatStr); // Output pqrsTUV测试suffix

        String splitStr = "a,b,c,d,e";
        String[] splitArr = splitStr.split(",");
        System.out.println(Arrays.toString(splitArr)); // Output [a, b, c, d, e]
    }
}

Replacement and Trimming Methods

Method Signature Function
String replace(char oldChar, char newChar) Replaces all occurrences of the old character with the new character
String replace(String oldStr, String newStr) Replaces all occurrences of the old substring with the new substring
String replaceAll(String regex, String replacement) Replaces all substrings matching the regular expression
String replaceFirst(String regex, String replacement) Replaces the first substring matching the regular expression
String trim() Removes leading and trailing whitespace from the string
package com.example.coreutil.string;

public class StringModifyMethodsSample {
    public static void main(String[] args) {
        String testStr = "xycdecfh";
        System.out.println(testStr.replace('c', 'X')); // Output xyXdeXfh
        System.out.println(testStr.replace("cd", "mn")); // Output xymnecfh

        System.out.println(testStr.replaceAll("c", "XX")); // Output xyXXdeXXfh
        System.out.println(testStr.replaceFirst("c", "O")); // Output xyOdecfh

        String spacedStr = "  qwe rty  ";
        System.out.println(spacedStr.length()); // Output 9
        System.out.println(spacedStr.trim().length()); // Output 7
        System.out.println(spacedStr.replace(" ", "").length()); // Output 6
    }
}

StringBuffer and StringBuilder Classes

The immutable characteristic of String leads to high memory overhead and low performance in frequent string modification scenarios. StringBuffer and StringBuilder are mutable string implementations that modify the underlying character array directly without creating new instances for each modification.

StringBuffer Class

StringBuffer is thread-safe, all its public methods are modified with the synchronized keyword, making it suitable for multi-threaded scenarios.

Add Methods

  • append(...): Appends the specified content to the end of the current string
  • insert(int offset, ...): Inserts the specified content at the specified index position
package com.example.coreutil.string;

public class StringBufferAddSample {
    public static void main(String[] args) {
        StringBuffer sb1 = new StringBuffer("wxyz");
        System.out.println(sb1.append("123")); // Output wxyz123

        StringBuffer sb2 = new StringBuffer(); // Default underlying array capacity is 16
        System.out.println(sb2.append("test")); // Output test

        StringBuffer sb3 = new StringBuffer(20); // Custom initial capacity
        sb3.append("abcde");
        sb3.append("fghij");
        System.out.println(sb3.append("klmno")); // Output abcdefghijklmno

        StringBuffer sb4 = new StringBuffer("abc");
        System.out.println(sb4.insert(2, "X")); // Output abXc
    }
}

Delete Methods

  • deleteCharAt(int index): Deletes the character at the specified index position
  • delete(int start, int end): Deletes characters from the start index (inclusive) to the end index (exclusive)
package com.example.coreutil.string;

public class StringBufferDeleteSample {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer("wxyz");
        System.out.println(sb.deleteCharAt(2)); // Output wxz
        System.out.println(sb.delete(0, 2)); // Output z
    }
}

Replace and Reverse Methods

  • replace(int start, int end, String str): Replaces characters from the start index (inclusive) to the end index (exclusive) with the specified string
  • reverse(): Reverses the character sequence of the current string
package com.example.coreutil.string;

public class StringBufferModifySample {
    public static void main(String[] args) {
        StringBuffer sb1 = new StringBuffer("abcxyz123");
        System.out.println(sb1.replace(0, 3, "ttt")); // Output tttxyz123

        StringBuffer sb2 = new StringBuffer("abcdefg");
        System.out.println(sb2.reverse()); // Output gfedcba
        String subStr = sb2.substring(0, 3);
        System.out.println(subStr); // Output gfe
    }
}

StringBuilder Class

StringBuilder has exactly the same API as StringBuffer, but it is not thread-safe (no synchronized modifiers on methods). It has higher performance than StringBuffer, making it suitable for single-threaded scenarios.

package com.example.coreutil.string;

public class StringBuilderSample {
    public static void main(String[] args) {
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder("wxyz");
        StringBuilder sb3 = new StringBuilder(30);

        System.out.println(sb2.append("123")); // Output wxyz123
        System.out.println(sb2.insert(2, " ")); // Output wx yz123
    }
}

Comparison of String, StringBuffer and StringBuilder

  • String: Immutable character sequence, low modification performance, suitable for scenarios where the string content does not change frequently.
  • StringBuffer: Mutable character sequence, thread-safe, slightly lower performance, suitable for frequent string modification in multi-threaded scenarios.
  • StringBuilder: Mutable character sequence, thread-unsafe, highest performance, suitable for frequent string modification in single-threaded scenarios.

Tags: java Java API wrapper classes String Class stringbuffer

Posted on Mon, 26 Oct 2026 16:41:26 +0000 by mrobertson