Object-Oriented Programming
Object Class
Analyze the root of the Java class hierarchy, object clone mechanics, and the deprecation of finalize.
Interview: Focuses on parent root method contracts, clone shallow copy constraints, and finalize garbage collection risks.
The java.lang.Object class is the root of the Java class hierarchy. Every class in Java inherits from Object, either directly or indirectly, inheriting a set of core methods.
Core Idea
Object is the universal parent class. It provides default implementations for equals, hashCode, toString, and wait/notify.
Why It Matters
Methods like clone() require classes to implement Cloneable, otherwise throwing a checked CloneNotSupportedException.
Interview Lens
Evaluates shallow vs deep copy differences, CloneNotSupportedExceptions, and finalize deprecation security risks.
Object Cloning: Shallow vs. Deep Copy
The clone() method creates a copy of an object:
- To use
clone(), a class must implement theCloneablemarker interface. Otherwise, callingsuper.clone()throws aCloneNotSupportedException. - Shallow Copy: The default implementation of
clone()copies primitive fields, but copies reference pointers for object fields. Both the original and cloned object share references to the same nested sub-objects. - Deep Copy: To isolate the clone, you must override
clone(), callsuper.clone(), and then explicitly clone all nested mutable reference objects manually.
The Deprecation of finalize()
The finalize() method was designed to perform cleanup before an object is garbage collected. It was deprecated in Java 9 and removed/deprecated-for-removal in modern versions due to serious design flaws:
- Unpredictable Execution: There is no guarantee when (or if) the garbage collector will run finalize, leading to resource leaks.
- Performance Bottleneck: Objects with finalizers slow down garbage collection allocation cycles.
- Security Vulnerability: A finalize method can resurrect objects by reassigning references during GC, bypassing constructor invariants.
Modern Alternative: Use the AutoCloseable interface combined with try-with-resources blocks for predictable resource cleanup.
Common Pitfalls
- Assuming clone() is deep: Using the default clone method and modifying shared nested structures, corrupting the original object.
- Using finalize() for resource cleanup: Relying on finalizers to close database connections or files, causing resource leaks.
- Calling clone() on non-Cloneable: Invoking clone on objects that do not implement Cloneable, throwing runtime exceptions.
Best Practices
- Avoid using the
clone()method altogether. Use copy constructors (e.g.public User(User other)) or factory methods to copy objects instead. - Implement
AutoCloseablefor classes that hold system resources (sockets, files) to enforce predictable cleanup. - Override
equals(),hashCode(), andtoString()to provide proper domain-specific behaviors.
Interview-Relevant Information
Q1: Why is finalize() deprecated, and what should be used instead?
Answer: finalize() is deprecated because its execution is unpredictable, it degrades garbage collection performance, and it introduces security vulnerabilities (finalizer attacks). Developers should use the AutoCloseable interface with try-with-resources instead.
Q2: What is the difference between a shallow copy and a deep copy during object cloning?
Answer: A shallow copy copies primitive values directly but copies reference addresses for object fields, sharing nested objects. A deep copy instantiates new copies of all nested mutable reference objects, ensuring the clone is completely isolated.
Quick Checklist
Can you differentiate shallow from deep copies, implement copy constructors, explain finalizer security vulnerabilities, and handle resource releases using AutoCloseable? If yes, you understand the Object class.
Use Cases
Refactoring system components to use AutoCloseable templates for connection closures.
Implementing copy constructors for safe data isolation before processing.
Common Mistakes
Assuming default clone() calls duplicate nested object states.
Using finalize() to release critical platform resources.