🧾 What Is the Default toString() Implementation in Java?
In Java, every class inherits the toString() method from the Object class.
If we don’t override this method in our own class, the default implementation provided by Object is used.
By default, the toString() method returns a string that includes:
This means:
-
The class name of the object.
-
Followed by the
@symbol. -
And finally, a hexadecimal value representing the object’s memory reference (derived from its hash code).
🧠 Example
Output:
Here,
-
Car→ is the class name. -
@→ separates the name and hash. -
5e91993f→ is the hexadecimal form of the object’s hash code.
✍️ Overriding toString()
If you override the toString() method, you can provide a custom, human-readable description of your object:
Output:
✅ In short:
The default toString() method returns the class name, followed by @, and the hexadecimal hash code of the object’s memory reference.
When overridden, it can display custom object details, making debugging and logging more meaningful.
⚖️ equals() Method vs. == Operator in Java
This is one of the most commonly asked interview questions in Java — and understanding the difference between == and equals() is crucial when comparing objects.
💡 The == Operator
-
The
==operator is used to compare references (memory locations) of two objects. -
It checks whether both variables point to the same object in memory.
-
Hence, it performs a shallow comparison.
🧠 Example
✅ Explanation:
Even though both objects contain the same data, u1 and u2 occupy different memory locations, so == returns false.
💡 The equals() Method
-
The
equals()method is defined in theObjectclass, so every Java class inherits it. -
By default, its implementation in
Objectalso performs a reference comparison (same as==). -
Therefore, if you don’t override it,
u1.equals(u2)will also return false in the above example.
To perform a deep comparison (compare contents, not references), you must override equals() in your class.
✍️ Overriding equals()
Now, comparing two objects with the same data will return true.
🧩 Special Cases — Strings, Wrappers, and Enums
There are exceptions where equals() is already overridden in the standard library classes to perform content-based (deep) comparison:
✅ Example with String
✅ Example with Wrapper Types
✅ Example with Enums
Enums are unique instances, so both comparisons return true.
🧠 Summary
| Aspect | == Operator | equals() Method |
|---|---|---|
| Type of Comparison | Reference comparison | Content (deep) comparison (if overridden) |
| Default Behavior | Compares memory locations | Same as == (unless overridden) |
| Can Be Overridden? | ❌ No | ✅ Yes |
| Used With | Primitives and objects | Objects only |
| Common Use | Check if two references point to the same object | Check if two objects have equal content |
✅ In short:
|
🔑 Difference Between |
| Keyword / Method | Type | Purpose | Can It Be Overridden / Guaranteed? |
|---|---|---|---|
final | Modifier | Prevent modification or inheritance (variables, methods, classes) | N/A |
finally | Block | Executes cleanup code in exception handling | Always executes |
finalize() | Method | Called by GC before object destruction | Not guaranteed, deprecated |
✅ In short:
final→ Used to restrict modification.finally→ Used for cleanup in exception handling.finalize()→ Used by GC before object deletion, but should be avoided in modern Java.
🧠 What Are Generics in Java?Generics were introduced in Java 5 to enable type-safe and reusable code. 💡 Problem Before GenericsBefore Java 5, collections could hold any type of object, because their types were not defined. For example:
This was allowed, but when retrieving data, you had to cast values manually, which could lead to
✅ Solution: Using GenericsWith Generics, you can declare the data type a collection can store:
Now, only integers are allowed — and type mismatches are caught at compile time instead of runtime. Generics bring:
🧩 Example
Here, each element is guaranteed to be a ⚙️ What Is Type Erasure?Type Erasure is how Java implements Generics — it ensures backward compatibility with older versions (pre-Java 5). At compile time, the compiler checks type safety using the generic types you specify. This ensures that older code (from Java 1.4 or 1.3) can still run on newer JVMs. 🧠 Example of Type Erasure
So, generics in Java exist only at compile time — they do not exist at runtime. 🧾 Summary
✅ In short:
|