The String.equals() method in Java compares two strings character-by-character to determine whether they contain the exact same text sequence, returning a boolean result.
Content Equality vs. Memory Address: Unlike primitive values compared with ==, comparing object references with == tests whether two variables point to the exact same memory address. The equals() method inspects the underlying character values. For case-insensitive checking, explore equalsIgnoreCase(). For alphabetical sorting orders, see compareTo(). To discover a character at an index, see charAt(), or check string lengths with length().
The equals() method is defined in java.lang.Object and overridden in java.lang.String:
// Formal signature of String.equals() in java.lang.String
public boolean equals(Object anObject)
| Parameter / Element | Type | Description & Operational Rule |
|---|---|---|
anObject |
Object |
The target object to compare against this String. Can be null or any object type. |
| Return Value | boolean |
Returns true if the given object is a String with identical characters in identical sequence; otherwise false. |
| Case Sensitivity | Strict | Differentiates uppercase and lowercase letters (e.g. "Java" does not equal "java"). |
When you invoke string1.equals(string2), Java compares the actual characters stored inside each string:
String site1 = "plus2net";
String site2 = "plus2net";
String site3 = "Plus2net";
System.out.println(site1.equals(site2)); // true (exact match)
System.out.println(site1.equals(site3)); // false (case mismatch)
System.out.println(site1.equals("2net")); // falseTerminal Output:
true
false
false
One of the most frequent sources of bugs in Java is confusing reference equality (==) with value equality (.equals()):
| Feature | string1.equals(string2) |
string1 == string2 |
|---|---|---|
| Comparison Target | Compares text values / contents. | Compares memory addresses / references. |
| String Pool Literals | Returns true if characters match. |
Returns true because literals share pooled address. |
Explicit new String() |
Returns true if characters match. |
Returns false because new object has distinct heap address. |
| Rule of Thumb | Always use for String comparison. | Only use for primitives (int, double, boolean). |
// String literals: Reused from String Constant Pool
String s1 = "Java";
String s2 = "Java";
// New object: Allocated on general Heap
String s3 = new String("Java");
System.out.println("s1 == s2: " + (s1 == s2)); // true (same pooled address)
System.out.println("s1 == s3: " + (s1 == s3)); // false (different heap memory)
System.out.println("s1.equals(s3): " + s1.equals(s3)); // true (same character content)Terminal Output:
s1 == s2: true
s1 == s3: false
s1.equals(s3): true
To optimize memory consumption, Java maintains a special area within heap memory known as the String Constant Pool:
[STACK MEMORY] [HEAP MEMORY]
s1 (ref: 0x1) ----+-----> [STRING POOL]
| "Java" (0x1)
s2 (ref: 0x1) ----+
[REGULAR HEAP]
s3 (ref: 0x2) -----------> new String("Java") (0x2)
s1 == s2 -> true (same pooled address 0x1)
s1 == s3 -> false (distinct address 0x2)
s1.equals(s3) -> true (same characters "Java")
When you declare string literals like String s1 = "Java";, the JVM checks the String Constant Pool. If the literal already exists, it returns the existing reference. When you explicitly instantiate with new String("Java"), the JVM bypasses reuse and allocates a brand new object on the heap.
If you call .equals() on a variable holding null, the JVM immediately throws a NullPointerException. To avoid crashes, use two production patterns:
"admin".equals(input). If input is null, the method safely returns false without throwing an exception.Objects.equals(): In Java 7+, use java.util.Objects.equals(a, b), which safely handles null checks for both arguments.String input = null;
// RISKY: Throws NullPointerException
try {
System.out.println(input.equals("admin"));
} catch (NullPointerException e) {
System.out.println("Caught NullPointerException!");
}
// SAFE APPROACH 1: "Yoda condition" (constant first)
System.out.println("admin".equals(input)); // false (no exception)
// SAFE APPROACH 2: Objects.equals()
System.out.println(java.util.Objects.equals(input, "admin")); // falseTerminal Output:
Caught NullPointerException!
false
false
When verifying promo codes, email domains, or user commands where case should not disqualify a match, use equalsIgnoreCase():
String code1 = "PROMO2026";
String code2 = "promo2026";
System.out.println("equals(): " + code1.equals(code2)); // false
System.out.println("equalsIgnoreCase(): " + code1.equalsIgnoreCase(code2)); // trueTerminal Output:
equals(): false
equalsIgnoreCase(): true
While equals() answers "Are these strings identical?" with a boolean, compareTo() answers "Which string comes first in alphabetical order?" by returning an integer:
String w1 = "apple";
String w2 = "banana";
String w3 = "apple";
System.out.println("w1.equals(w2): " + w1.equals(w2)); // false
System.out.println("w1.compareTo(w2): " + w1.compareTo(w2)); // -1 ('a' comes before 'b')
System.out.println("w1.compareTo(w3): " + w1.compareTo(w3)); // 0 (exact match)Terminal Output:
w1.equals(w2): false
w1.compareTo(w2): -1
w1.compareTo(w3): 0
Passing a StringBuilder or StringBuffer to String.equals() always returns false because equals() enforces type equality. To compare contents across different character sequences, use contentEquals():
String text = "plus2net";
StringBuilder sb = new StringBuilder("plus2net");
// TRAP: equals() returns false because sb is not a String!
System.out.println("equals(): " + text.equals(sb)); // false
// CORRECT: contentEquals() compares any CharSequence
System.out.println("contentEquals(): " + text.contentEquals(sb)); // trueTerminal Output:
equals(): false
contentEquals(): true
Real-world applications sanitize whitespace and handle null checks gracefully before checking credentials or user permissions:
public class RoleValidator {
public static boolean hasAdminAccess(String userRole) {
// Sanitize nulls and surrounding spaces
if (userRole == null) return false;
return "admin".equalsIgnoreCase(userRole.trim());
}
public static void main(String[] args) {
System.out.println("Role check: " + hasAdminAccess(" ADMIN ")); // true
System.out.println("Null check: " + hasAdminAccess(null)); // false
}
}Terminal Output:
Role check: true
Null check: false
Strings retrieved from scanners, databases, or web forms are dynamically allocated on the heap. Comparing them with == yields false even if characters match. Always use .equals().
Writing userRole.equals("ADMIN") causes a server crash if userRole is null. Writing "ADMIN".equalsIgnoreCase(userRole) safely returns false.
Yes. The parameter type is Object. If you pass an object of any type other than String (such as an Integer or StringBuilder), it returns false without throwing an error.
As an optimization, equals() first checks this == anObject. If true, it returns immediately; otherwise, it checks if lengths match and compares characters individually.
Do not use array1.equals(array2). Use java.util.Arrays.equals(array1, array2) to compare element contents.
Yes. It runs in O(N) linear time where N is the length of the string, exiting on the first mismatched character.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.