Primitive Type Wrapper Classes
Wraper classes serve two core purposes in Java:
- Provide object-oriented representations of primitive data types, allowing primitives to be used in collection frameworks that only accept objects.
- 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:
- 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. - 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 instanceString(String content): Creates a string with the specified contentString(byte[] byteArr): Creates a string by decoding the specified byte array using the default platform encodingString(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 stringinsert(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 positiondelete(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 stringreverse(): 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.