Can you change String value via reflection?
Technically — yes, through the Reflection API you can change the internal contents of a string, but this is very bad practice.
Junior Level
Technically — yes, through the Reflection API you can change the internal contents of a string, but this is very bad practice.
String s = "Hello";
// Access the private field value
// In Java 8 and earlier the field was char[] value. Starting with Java 9 (Compact Strings) — byte[] value.
Field field = String.class.getDeclaredField("value");
field.setAccessible(true);
byte[] value = (byte[]) field.get(s);
value[0] = 'J'; // Change 'H' to 'J'
System.out.println(s); // Prints "Jello"
Why this is bad:
- The string changes everywhere where
"Hello"is used (string pool) hashCodebreaks — the string gets lost inHashMap- This is a JVM security violation
WARNING: This technique MUST NOT be used in production code. It is a security violation that breaks the JVM. Educational purposes only.
Middle Level
Consequences
-
String Pool breakage — the string changes everywhere the literal is used (logs, configs, class names)
-
HashMap breakage —
StringcacheshashCode. After changing thevaluearray, the string contents change but the hash remains the old one → the object cannot be found inHashMap -
Security Bypass — security checks (file access, URLs) are based on strings. Changing a string “after validation” is a classic vulnerability
Protection in modern JDKs
In Java 17+, access to internal fields of java.base via reflection is blocked by the module system (Project Jigsaw). You get InaccessibleObjectException.
You can bypass it with launch flags (--add-opens java.base/java.lang=ALL-UNNAMED), but this is not feasible in production.
Senior Level
Full attack example
String s = "admin";
Field valueField = String.class.getDeclaredField("value");
valueField.setAccessible(true);
byte[] value = (byte[]) valueField.get(s);
// Change "admin" to "hacker"
value[0] = 'h'; value[1] = 'a'; value[2] = 'c';
value[3] = 'k'; value[4] = 'e'; value[5] = 'r';
Deep consequences
- ClassLoader pollution — class names, loaders, paths — everything can be compromised
- Security Manager — if used, checks can be bypassed
- SerialVersionUID — depends on class name, can be compromised
Evolution of protection
- Java 8 and earlier:
setAccessible(true)worked without restrictions - Java 9: module system restricted access to
java.base - Java 16+:
InaccessibleObjectExceptionby default - Java 17+:
--illegal-access=denyby default
Summary for Senior
- Reflection attack on
String— an example of how low-level manipulations destroy high-level guarantees - Modern JDKs (17+) block this at the module level
- In production with correct flags this is impossible
- For Senior: this illustrates the importance of encapsulation at all levels
Interview Cheat Sheet
Must know:
- Technically possible via
setAccessible(true)on thevaluefield, but it’s a security violation - Consequences: String Pool breakage (changes everywhere), hashCode breaks (lost in HashMap), Security Bypass
- Java 9+: module system restricted access; Java 16+:
InaccessibleObjectExceptionby default - Java 17+:
--illegal-access=deny— reflection to java.base is blocked - Can be bypassed with flags (
--add-opens), but not feasible in production - This MUST NOT be used in production — educational purposes only
Frequent follow-up questions:
- Does it work in Java 17+? — No,
InaccessibleObjectExceptionwithout--add-opens - What breaks if you change a string? — All uses of that literal, hashCode in HashMap, Security Manager
- What is ClassLoader pollution? — Class names, loaders, paths — everything can be compromised
- Does SerialVersionUID depend on this? — Yes, depends on class name, can be compromised
Red flags (do NOT say):
- “This is a normal production technique” — it’s a JVM security violation
- “Reflection works in any version” — in Java 16+ it’s blocked for java.base
- “Only this string changes” — ALL instances of that literal in the pool change
- “You can add a flag in production” —
--add-opens java.base/java.lang=ALL-UNNAMED— security risk
Related topics:
- [[4. Why is String class immutable]]
- [[5. What are the consequences of String immutability]]
- [[18. How does String pool work and how is it related to immutability]]
- [[8. Is it enough to make all fields final for immutability]]