I'm always excited to take on new projects and collaborate with innovative minds.
contact@niteshsynergy.com
https://www.niteshsynergy.com/
OOP→
FC→
✅ Java.lang Package – Cleaned & Modernized Study Notes
java.lang
Package in JavaIn Java, some of the most essential and frequently used classes and interfaces are grouped under the java.lang
package. This package is fundamental to Java development, as it provides core functionalities that are crucial for any Java program, including object manipulation, string operations, memory management, and number handling.
java.lang
package is automatically available to all Java programs, so there's no need to explicitly import it.java.lang
Below are some of the most important and commonly used classes in the java.lang
package:
Object
ClassObject
.equals()
, hashCode()
, toString()
, clone()
, getClass()
, and finalize()
.public Object() {}
– The Default ConstructorThis is the only constructor defined in the Object
class in Java.
super()
).Object
class?The Object
class is the root class of the Java class hierarchy. Every class in Java, whether directly or indirectly, inherits from Object
.
Object
doesn’t need any initial state or fields.super(...)
, the Java compiler automatically inserts a call to super()
(i.e., the no-arg constructor).Object
is designed to be lightweight and abstract.@IntrinsicCandidate
?@IntrinsicCandidate
is a JVM internal annotation, introduced in newer Java versions (starting from Java 15+), used mainly by the HotSpot VM (Java's runtime engine).
Object()
constructor as a candidate for low-level optimization when objects are created.➡️ You can ignore this annotation in normal Java development—it’s not intended for use in user code.
Aspect | Description |
---|---|
public Object() | The only constructor in Object class – no arguments, does nothing directly. |
Why only one constructor? | Simplicity, support for inheritance, and because Object has no state. |
@IntrinsicCandidate | JVM hint for optimizing object creation. |
@IntrinsicCandidate public native int hashCode();
hashCode()
?hashCode()
is a native method in Java that returns an integer hash code for the object.It's defined in Object
class as:
native
keyword means:HashMap
HashSet
Hashtable
By default, hashCode()
returns a number that is typically derived from the object’s memory address.
equals()
.public boolean equals(Object obj) { return (this == obj); }
equals()
?equals(Object obj)
method is used to compare two objects for equality.Object
class.this == obj
mean?==
checks whether both references point to the exact same object in memory.equals()
by default is reference comparison, not content comparison.equals()
, your class will compare by reference.equals()
, you can compare based on content or business logic.
These two are tightly coupled in Java, especially in hash-based collections.
Now, new Employee(1, "Nitesh")
and new Employee(1, "Nitesh")
will be treated as equal and will have the same hash code — perfect for use in HashSet
.
Method | Type | Default Behavior | Can be Overridden? | Used In |
---|---|---|---|---|
hashCode() | Native | Returns int based on memory address | ✅ Yes | HashMap , HashSet |
equals() | Java | Compares object references (this == obj ) | ✅ Yes | Comparing objects |
hashCode()
and equals()
in a Child ClassIf your custom class does not override equals()
and hashCode()
, it inherits them from the Object
class, where:
equals()
→ compares object references (memory addresses)obj1 == obj2
hashCode()
→ returns a hash based on memory address, via a native implementation in the JVM.
Even though
p1
andp2
have the same content, they are not considered equal and have different hash codes, because we didn’t overrideequals()
andhashCode()
.
Condition | equals() Behavior | hashCode() Behavior | Outcome |
---|---|---|---|
Not Overridden | Compares memory address (== ) | Returns address-based hash code | ❌ Not suitable for logical content comparison |
In Collections like HashMap | Objects with same content are not matched unless same reference | Keys will be missed or duplicated unexpectedly | ❌ Broken behavior |
Why?
HashSet calls:
hashCode()
to find the bucketequals()
to check equalityBut both are comparing reference, so it thinks they are different objects.
To make objects compare by logical content, override both:
equals()
→ define logical equalityhashCode()
→ generate hash code based on significant fieldsNow:
Aspect | Without Overriding |
---|---|
equals() behavior | Compares by reference only (== ) |
hashCode() behavior | JVM-generated hash based on object memory |
Logical comparison | ❌ Fails — even if content is same |
Hash-based collections | ❌ Unreliable behavior — duplicates possible |
When to override | ✅ Always override both when using custom objects in collections or comparing by content |
getClass()
?getClass()
is a final native method defined in the Object
class.Class<?>
object that represents the runtime class of the current object.Keyword | Meaning |
---|---|
@IntrinsicCandidate | JVM-level hint for intrinsic/native optimization (low-level feature) |
public | Accessible from anywhere |
final | Cannot be overridden by any subclass |
native | Implemented in native code (like C/C++), not Java |
Class<?> | Generic return type indicating it returns a Class object |
getClass()
useful?Even though obj
is declared as Object
, getClass()
still knows the real type.
String name = "Nitesh" ; Class<?> cls = name.getClass(); System.out.println(cls.getName()); // java.lang.String System.out.println(cls.getSimpleName()); // String
Class.forName("...")
)
final
and native
?final
getClass()
would break the JVM's type safety and behavior.native
getClass()
simply fetches this info directly from the memory structure using native code.
Feature | Description |
---|---|
Method Name | getClass() |
Return Type | Class<?> (Java Reflection class) |
Defined In | java.lang.Object |
Native | ✅ Yes (implemented in C/C++ inside JVM) |
Final | ✅ Yes (cannot be overridden) |
Use | Get the actual class of the object at runtime |
Common Use Cases | Reflection, debugging, dynamic loading, frameworks |
Even though num
is of type Number
, getClass()
returns Integer
.
protected native Object clone () throws CloneNotSupportedException;
clone()
The clone()
method is used to create and return a copy of the current object. It's a shallow copy by default, unless you manually implement deep copying.
clone()
is needed?When you assign an object like this:
Person p1 = new Person("Nitesh");
Person p2 = p1;
You are not copying the object. You are copying the reference (both point to the same memory).
But in some cases (e.g., undo operations, version control, simulation), you need a copy of the object with independent memory — that's where clone()
comes in.
clone()
Keyword ExplanationKeyword | Meaning |
---|---|
@IntrinsicCandidate | JVM optimization hint |
protected | Only accessible within the same package or subclass |
native | Implemented in JVM native code (not Java) |
Object | Return type is an Object — must cast manually |
throws CloneNotSupportedException | You must explicitly handle this if the class is not Cloneable |
CloneNotSupportedException
This is a checked exception, which is thrown when:
Your class does not implement the
Cloneable
interface, but you're trying to callclone()
.
clone()
properly?Cloneable
interface (marker interface — no methods).clone()
method from Object
.super.clone()
inside it.CloneNotSupportedException
.Type | Meaning |
---|---|
Shallow Clone | Creates a new object, but references the same internal objects. |
Deep Clone | Creates a new object and recursively clones all internal objects. |
If the object contains references (like a List
, or nested objects), you must manually deep clone them.
Feature | Description |
---|---|
Purpose | Creates a copy of the object (not just reference) |
Default Copy Type | Shallow (fields copied, but objects referenced are not cloned) |
Need to implement | Cloneable interface |
Throws Exception | CloneNotSupportedException if not Cloneable |
Return type | Object — needs casting |
Access modifier | protected — must override to access from outside class |
protected
?clone()
Some developers avoid clone()
due to complexity and prefer:
toString()
in Object
classIt gives a string representation of the object in this format:
ClassName @HashCodeInHex
Person p = new Person (); System.out.println(p.toString()); // e.g., com.demo.Person@1a2b3c
getClass().getName()
com.mycompany.model.Employee
hashCode()
Integer.toHexString(int i)
int
(from hashCode()
) to a hexadecimal string.
toString()
Purpose | Benefit |
---|---|
Debugging/logging | See object info in logs or exceptions |
Default representation | Avoids nulls in string conversions |
IDE/Debugger tools | Displays concise object info |
Let’s explore all combinations of overriding:
toString()
nor hashCode()
overridden→ Default behavior, shows technical object info.
hashCode()
overridden→ You changed how the hash is calculated, so it affects the toString()
output.
toString()
overridden→ Much more readable and meaningful for logs, UIs, etc.
Hashcode is still default, but unused unless you call hashCode()
explicitly.
toString()
and hashCode()
overridden→ Full control over both:
hashCode()
for hashing, collections, equality.toString()
for display, logging.
toString()
?System.out.println(obj)
gives readable output)
toString()
:
If you don’t override:
MyClass@7852e922
(useless for business logic)
Case | toString() Output | Human Readable? | Controlled Behavior |
---|---|---|---|
No override | Class@HexHash | ❌ | ❌ |
Only hashCode() overridden | Class@CustomHex | ❌ | ⚠️ (affects Map/Set) |
Only toString() overridden | Meaningful string | ✅ | ✅ |
Both overridden | Your string with custom logic | ✅ | ✅ |
toString()
when your class is used in logs, UI, or debugging.hashCode()
when you also override equals()
(important for collections like HashSet
, HashMap
).toString()
= displayhashCode()
= identity & hashing
Object
Class: how it works, why it was deprecated, real use cases, and modern alternatives.
finalize()
?finalize()
is a method in java.lang.Object
that was intended to be called by the Garbage Collector (GC) before reclaiming memory from an object.
finalize()
finalize()
once only before destroying the object
finalize()
is Deprecated (Since Java 9)finalize()
will be called at all.finalize()
throws an exception and doesn’t call super.finalize()
, GC can break.finalize()
can resurrect them, delaying collection (memory leak risk).
This object won’t be garbage collected, leading to memory leaks!
try-with-resources
or AutoCloseable
:Instead of relying on finalize()
, use this:
This ensures deterministic cleanup of resources like files, DB connections, etc.
Feature | finalize() |
---|---|
Introduced In | Java 1.0 |
Deprecated Since | Java 9 |
Unreliable? | ✅ Yes – GC timing is unpredictable |
Replaced By | AutoCloseable + try-with-resources |
Can throw? | Yes – Throwable (broadest exception) |
Dangerous? | ✅ Yes – possible resurrection & leaks |
Never use finalize()
in new code.
If you're maintaining legacy code that still uses it:
AutoCloseable
.
→ Rest Other method of Object class will take in multithreading→
String
ClassExample:
StringBuffer
ClassString
).StringBuffer
– Thread-safe Mutable Strings→ StringBuffer is not 100% synchronized remember. Most of StringBuffer methods are synchronized not all. If someone say directly like StringBuffer all synchronized methods then this is not valid.
As below methods are not synchronized.
private void readObject (ObjectInputStream s )
private static final ObjectStreamField [] serialPersistentFields =
public int lastIndexOf (String str ) {
public int indexOf (String str ) {
public StringBuffer insert (int offset , double d ) {
public StringBuffer insert (int offset , float f ) {
Ex:-
StringBuffer sb = new StringBuffer("Hi");
sb.append(" Java");
System.out.println(sb); // Hi Java
StringBuilder
Class (Introduced in Java 1.5)StringBuffer
in single-threaded environments.StringBuilder
– High Performance, Not Thread-SafeStringBuffer
but not thread-safeStringBuilder sb = new StringBuilder("Hi");
sb.append(" Java");
System.out.println(sb); // Hi Java
StringBuilder
over StringBuffer
when no multithreading is involved.Feature | String | StringBuffer | StringBuilder |
---|---|---|---|
Mutability | Immutable | Mutable | Mutable |
Thread-safe | Yes (because immutable) | Yes (synchronized) | ❌ No |
Performance | Medium | Slow (due to sync) | Fast (no sync) |
Use Case | Constants, Keys | Multi-threaded ops | High-perf single thread |
Equals/hashCode | ✅ Overridden | ❌ Inherited | ❌ Inherited |
String
is Immutable🔒 Prevents:
String
, StringBuffer
, and StringBuilder
override equals()
and hashCode()
?Class | equals() Overridden? | hashCode() Overridden? | Why / Why Not? |
---|---|---|---|
String | ✅ YES | ✅ YES | To compare contents, support HashMap , Set , etc. |
StringBuffer | ❌ NO (inherits Object ) | ❌ NO (inherits Object ) | Uses reference equality, not designed for content comparison |
StringBuilder | ❌ NO (inherits Object ) | ❌ NO (inherits Object ) | Same as StringBuffer , avoids overhead |
String
→ ✅ OVERRIDDENequals()
:hashCode()
:String
is heavily used in collections like HashMap, HashSet.
StringBuffer
→ ❌ NOT OVERRIDDENObject
.
StringBuilder
→ ❌ NOT OVERRIDDENStringBuffer
.String
Overrides?Feature | String | StringBuffer/Builder |
---|---|---|
Immutable | ✅ Yes | ❌ No |
Thread-safe | ✅ Yes | Buffer: ✅, Builder: ❌ |
Used as Key in HashMap | ✅ Common | ❌ Rare |
Consistent Content | ✅ Fixed | ❌ Can change anytime |
Hashing is Safe | ✅ Yes | ❌ No |
String
overrides both equals()
and hashCode()
→ for content comparison, safe to use in HashMap.StringBuffer
& StringBuilder
do NOT override → because they're mutable, and using them in hash-based collections would cause unexpected behavior if the content changes after insertion.String
is immutable, pooled, and equals/hashCode are overridden.StringBuffer
is thread-safe but slower.StringBuilder
is fast but not thread-safe.
Java provides object representations for all primitive data types via wrapper classes:
Primitive Type | Wrapper Class |
---|---|
int | Integer |
float | Float |
char | Character |
boolean | Boolean |
double | Double |
byte | Byte |
short | Short |
long | Long |
These classes allow primitives to be used in collections and support utility methods for conversions and parsing.
Autoboxing: Automatic conversion of a primitive type to its corresponding wrapper class.
Unboxing: Automatic conversion of a wrapper class object back to a primitive.
The java.lang
package forms the backbone of Java's core libraries. With classes like Object
, String
, and utility types such as wrappers and builders, it equips developers with powerful tools to build efficient and robust Java applications. Since it's implicitly available in every Java program, you can start using its classes and interfaces without worrying about imports—making development quicker and more streamlined.
Your email address will not be published. Required fields are marked *