Two Java variables can print the same characters while == is false. A single new expression or runtime concatenation can change the answer, even when the visible text is identical. Literals, the string pool, new String(...), intern(), ==, and equals() determine reference identity, content equality, and object counts in Java.
For the broader immutability, StringBuilder, and fresher-test foundation, start with String Handling in Java: String Pool, Immutability and Fresher-Test Questions. Reference-identity problems go further: intern(), compile-time versus runtime concatenation, and assumption-bound object counts determine the answer.
Java String basics: object, literal, and pool
java.lang.String is an immutable class whose objects represent character sequences. Keep three ideas separate: "Java" is a value, a variable such as a holds a reference, and that reference points to a String object. Two references can therefore lead to objects with equal values without being the same reference.
The string pool is the JVM's canonicalisation table for interned strings. String literals and compile-time constant strings use canonical pooled references. new String(...) explicitly creates a distinct String object, while intern() returns the canonical pooled reference for the same content. It does not modify the object on which it is called.
Expression | Reference obtained | Identity implication |
|---|---|---|
| Canonical reference for the literal | Another use of the same literal normally reuses it |
| Reference to a distinct object | It is not identical to the pooled literal object |
| Canonical pooled reference | If |
This model is about reference behaviour. You do not need to imagine the pool as a physically separate memory area to solve these questions.
Java string pool worked example: trace five references
Trace this code one statement at a time:
String a = "Java";
String b = "Java";
String c = new String("Java");
String d = c.intern();
String e = new String("Java").intern();a obtains the canonical reference for "Java", and b reuses it. Thus a == b is true. The new expression gives c a distinct reference, so a == c is false. Calling c.intern() returns the canonical reference without changing c; therefore a == d is true and c == d is false.
The last line first creates another distinct object, then intern() returns the canonical reference to e. Hence a == e is true. Content is equal throughout, so a.equals(c) is true.
For object counting, state the scope. Assume "Java" was not interned before this class loaded, count only String objects attributable to these statements, and exclude backing arrays and JVM helper objects. The count is 1 + 1 + 1 = 3: one canonical literal object, the object referenced by c, and the temporary object created in the final line. After assignment, e points to the canonical object, so none of these variables retains that temporary object.

Java String comparison: == versus equals()
For objects, == compares reference identity. String.equals() compares character content. The earlier variables make the difference exact:
Check | Result | Reason |
|---|---|---|
|
| Both hold the canonical reference |
|
|
|
|
| Both values contain |
|
| The references differ, but the content matches |
Content comparison is case-sensitive: "Java".equals("java") is false. By contrast, "Java".equalsIgnoreCase("java") is true. Use equals() when the question is whether text matches. Reserve == for the rare case where reference identity itself matters, not merely because two literals happen to share a pooled reference.
Java string concatenation: compile-time pooling versus runtime objects
Compilation time changes what can be canonicalised before the program runs:
String base = "Knowledge";
String suffix = "Gate";
String pooled = "KnowledgeGate";
String compileTime = "Knowledge" + "Gate";
String runTime = base + suffix;
String canonical = runTime.intern();The compiler folds the two literal operands into the existing "KnowledgeGate" constant. Therefore compileTime == pooled is true. base and suffix are non-final variables, so their concatenation happens at runtime and produces a distinct result object. Thus runTime == pooled is false, while runTime.equals(pooled) is true. Finally, canonical == pooled is true because intern() returns the canonical reference.
Assume these literals were not previously interned and count only relevant String objects. There are four: pooled "Knowledge", pooled "Gate", pooled "KnowledgeGate", and the distinct runtime result "KnowledgeGate". In arithmetic form, 3 pooled + 1 runtime = 4. Neither compileTime nor canonical adds a new String object.

Java String immutability: what changes and what does not
Consider String original = "Java"; String changed = original.concat(" Pool");. The value of original remains "Java", changed is "Java Pool", and original == changed is false. A reference variable may be reassigned, but the content of a String object is never edited in place.
Immutability makes sharing pooled strings safe because one user cannot alter the shared value for everyone else. It also keeps a string's content-based hash stable while the string is used as a map key. Hashing and Collision Resolution extends that idea into hash functions, buckets, and collision-handling methods.
For repeated construction, use a mutable builder:
StringBuilder builder = new StringBuilder("Java");
builder.append(" Pool");
String built = builder.toString();The builder changes during construction. The final value of built is exactly "Java Pool", and built is an immutable String.
Java string object-counting questions: make assumptions explicit
Interview-style object counts are meaningful only when their scope is stated:
String x = "red";
String y = "red";
String z = new String("red");
String p = "blue";
String q = new String("blue");Assume neither literal was already interned by another loaded class, count only String objects introduced by this snippet, and ignore backing arrays. The answer is four objects: one pooled red, one explicit new red, one pooled blue, and one explicit new blue. The calculation is 1 + 1 + 1 + 1 = 4; y reuses pooled red and adds nothing.
The exact checks are x == y is true, x == z is false, p == q is false, x.equals(z) is true, and z.intern() == x is true. If an object-count question omits the counting scope or the pre-existing-pool assumption, it is underspecified.
Java string pool traps and interview patterns
Trap | Wrong assumption and consequence | Better action |
|---|---|---|
Use | Equal content may arrive in distinct objects, so the check can be false | Compare content with |
Write | It creates a distinct object without a useful identity requirement | Use the literal unless distinct identity is genuinely needed |
Expect variable concatenation to reuse a literal reference | Runtime concatenation can create equal content at a different reference | Use |
Intern unbounded user data as a default optimisation | The canonicalisation table can add memory and lookup pressure | Intern only for a measured need with a controlled value domain |
The three common question forms reduce to the same model: predict boolean output, count objects under stated assumptions, or separate compile-time constants from runtime expressions. Apply the reference model in that order before choosing an answer. The Coding & DSA Courses for Placements category is a useful next path for tracing object construction and reference-based structures.
Java strings and string pool: the short version and next step
Keep six rules together:
Literals reuse canonical references.
new String(...)creates a distinct object.intern()returns the canonical reference and does not mutate its caller.==checks identity.equals()checks content.Compile-time literal concatenation can be pooled, while runtime variable concatenation creates a distinct result.
If you are building the language from the beginning, Complete Java provides the full Java sequence. If your next target is coding-round problem solving, DSA using Java carries that Java foundation into data structures and algorithms.




