A comprehensive reference for all the ways to construct a String in Java.

1. String Literals

String s = "Hello";          // from string pool
String s = "";               // empty literal

2. new String(...) Constructors

// From another String
String s = new String("Hello");
String s = new String(existingStr);

// From char array
char[] chars = {'J', 'a', 'v', 'a'};
String s = new String(chars);            // "Java"
String s = new String(chars, 1, 2);     // offset=1, count=2 → "av"

// From byte array
byte[] bytes = {72, 101, 108, 108, 111};
String s = new String(bytes);                        // uses default charset
String s = new String(bytes, StandardCharsets.UTF_8);
String s = new String(bytes, 1, 3, "UTF-8");        // offset, length, charset

// From StringBuilder / StringBuffer
String s = new String(new StringBuilder("Hello"));
String s = new String(new StringBuffer("Hello"));

// From int[] codepoints
int[] codePoints = {72, 101, 108, 108, 111};
String s = new String(codePoints, 0, codePoints.length);

3. String Static Factory Methods

String s = String.valueOf(42);           // int → "42"
String s = String.valueOf(3.14);         // double → "3.14"
String s = String.valueOf(true);         // boolean → "true"
String s = String.valueOf('c');          // char → "c"
String s = String.valueOf(obj);          // Object → obj.toString() or "null"
String s = String.valueOf(chars);        // char[] → "Java"

String s = String.format("Hi %s, age %d", "Kai", 20);
String s = String.formatted("Hi %s", "Kai");   // Java 15+

String s = String.copyValueOf(chars);           // same as valueOf(char[])
String s = String.copyValueOf(chars, 1, 2);     // offset + count

4. From StringBuilder / StringBuffer

String s = new StringBuilder("Hello").append(" World").toString();
String s = new StringBuffer("Hello").reverse().toString();

5. Concatenation

String s = "Hello" + " " + "World";     // compile-time constant folding
String s = a + b;                        // runtime: uses StringBuilder internally
String s += " more";

6. String Instance Methods (Return a New String)

str.substring(1, 4)
str.toLowerCase() / str.toUpperCase()
str.trim() / str.strip()                // strip() is Unicode-aware (Java 11+)
str.replace('a', 'b')
str.replaceAll("regex", "val")
str.concat("suffix")
str.intern()                            // returns canonical pool reference

7. Joining & Collecting

String s = String.join(", ", "a", "b", "c");           // "a, b, c"
String s = String.join("-", List.of("x", "y"));

StringJoiner sj = new StringJoiner(", ", "[", "]");
sj.add("a"); sj.add("b");
String s = sj.toString();                               // "[a, b]"

String s = Stream.of("a","b","c")
                 .collect(Collectors.joining(", "));

8. Conversion from Other Types

String s = Integer.toString(42);
String s = Integer.toBinaryString(10);   // "1010"
String s = Integer.toHexString(255);     // "ff"
String s = Double.toString(3.14);
String s = Character.toString('A');
String s = Arrays.toString(new int[]{1,2,3});  // "[1, 2, 3]"

Key mental model: String is immutable, so every method that "changes" it actually returns a new String object. The string pool only applies to literals and .intern()new String(...) always allocates on the heap.