Inheritance Hierarchy
The String class implements several key interfaces that define its capabilities:
- Serializable: Enables object serialization for network transmission
- Comparable: Allows string comparison operations
- CharSequence: Defines the character sequence contract
- Constable, ConstantDesc: Advanced features for compile-time constants
Here's a glimpse of the class definition:
public final class String
implements java.io.Serializable, Comparable<string>, CharSequence,
Constable, ConstantDesc {
@Stable
private final byte[] value;
// ... additional implementation details
}</string>
Key characteristics:
- String is a final class, preventing inheritance
- Internally uses a final byte array for character storage
String Comparison: == vs equals()
Understanding how String comparison works is crucial:
String text1 = "hello";
String text2 = "hello";
String text3 = new String("hello");
String text4 = new String("hello");
System.out.println(text1 == text2); // true - same string pool reference
System.out.println(text3 == text4); // false - different objects
System.out.println(text1 == text4.intern()); // true - interned reference
System.out.println(text1.equals(text2)); // true - content comparison
System.out.println(text3.equals(text4)); // true - content comparison
String Constructors
The String class provides multiple constructors for differant initialization scenarios:
// Discovering String constructors programmatically
Class<String> stringClass = String.class;
Constructor[] constructors = stringClass.getDeclaredConstructors();
int constructorCount = 0;
for (Constructor constructor : constructors) {
System.out.println("Constructor #" + (++constructorCount) + ": " + constructor);
}
String Object Creation Analysis
Let's examine how many objects are created in different scenarios:
Scenario 1:
String greeting = "welcome";
greeting = "goodbye";
Two objects are created: one for "welcome" and another for "goodbye".
Scenario 2:
String combined = "hello" + "world";
Only one object is created. The compiler optimizes this to combined = "helloworld".
Scenario 3:
String part1 = "hello";
String part2 = "world";
String full = part1 + part2;
Three objects are created:
- "hello" in the string pool
- "world" in the string pool
- A StringBuilder is created, which appends both parts and converts to "helloworld"
Essential String Methods
The String class provides numerous methods for manipulation and examination:
| Return Type | Method | Description |
|---|---|---|
| boolean | equals(Object obj) | Compares this string to the specified object. |
| boolean | equalsIgnoreCase(String another) | Compares ignoring case differences. |
| int | length() | Returns the string length. |
| int | indexOf(String str) | Finds first occurrence of substring. |
| int | lastIndexOf(int ch) | Finds last occurrence of character. |
| String | substring(int begin, int end) | Exrtacts substring portion. |
| String | toUpperCase() | Converts to uppercase. |
| String | toLowerCase() | Converts to lowercase. |
| String | concat(String str) | Concatenates another string. |
| boolean | contains(CharSequence s) | Checks if substring exists. |
| String | replace(char old, char new) | Replaces characters. |
| String[] | split(String regex) | Splits into array by regex. |
| char[] | toCharArray() | Converts to character array. |
| int | compareTo(String another) | Lexicographical comparison. |
String Formatting
The format method provides powerful string templating:
String name = "Alice";
int age = 30;
double score = 95.5;
char grade = 'A';
String template = "Name: %s, Age: %d, Score: %.1f, Grade: %c";
String result = String.format(template, name, age, score, grade);
System.out.println(result); // Name: Alice, Age: 30, Score: 95.5, Grade: A
Mutable String Alternatives
For frequent modifications, consider StringBuffer or StringBuilder:
StringBuffer (thread-safe):
- Designed for multi-threaded environments
- All methods are synchronized
- Suitable when thread safety is required
StringBuilder (non-thread-safe):
- Faster than StringBuffer due to lack of synchronization
- Preferred for single-threaded scenarios
- Memory efficient for frequent modifications
StringBuffer Implementation
Here's the StringBuffer class structure:
public final class StringBuffer
extends AbstractStringBuilder
implements Serializable, Comparable<StringBuffer>, CharSequence
{
// ... implementation details
}
Key notes:
- Final class, cannot be extended
- Uses byte array storage (since Java 9) for memory efficiency
StringBuffer Constructors
| Constructor | Description |
|---|---|
| StringBuffer() | Creates empty buffer with 16-character capacity. |
| StringBuffer(int capacity) | Creates buffer with specified initial capacity. |
| StringBuffer(CharSequence seq) | Creates buffer with characters from sequence. |
| StringBuffer(String str) | Creates buffer initialized with string content. |
StringBuffer Methods
| Method | Description |
|---|---|
| append(String s) | Appends string to buffer. |
| reverse() | Reverses character sequence. |
| delete(int start, int end) | Removes substring. |
| insert(int offset, int i) | Inserts integer representation. |
| insert(int offset, String str) | Inserts string at position. |
| replace(int start, int end, String str) | Replaces substring. |
| indexOf(String str) | Finds first occurrence. |
Conversion Between String and StringBuffer
| String to StringBuffer | StringBuffer to String |
|---|---|
| new StringBuffer(String value) | new String(StringBuffer buffer) |
| buffer.append(String value) | String result = buffer.toString(); |
Capacity Management
Both StringBuffer and StringBuilder use the same expansion strategy:
- Initial capacity: 16 characters (default constructor)
- Growth formula:
newCapacity = (oldCapacity * 2) + 2 - Ensures amortized constant time append operations