Definition
Six ways to create objects:
- new:
Account a = new Account(...)– calls the constructor directly. Most common. - Reflection:
Class.forName(...).getDeclaredConstructor().newInstance()– creates objects dynamically by name. - clone():
account.clone()– copies an existing object. - Deserialization:
ObjectInputStream.readObject()– creates from bytes without constructor. - Factory method:
Account.create(...)– static method that encapsulates construction. - DI framework: Spring creates beans via reflection based on annotations.
Six ways to open a bank account: walk into the branch (new), send a remote instruction with the account type name (reflection), photocopy an existing passbook (clone), restore from backup (deserialization), ask the relationship manager to handle it (factory), or let the branch manager assign one automatically (Spring DI).
Understanding the Concepts
1. new keyword
Account rajesh = new Account("SAV2001", new BigDecimal("500000"));
Most common. Calls the constructor. Type checked at compile time.
2. Reflection
Class<?> clazz = Class.forName("com.bank.core.Account");
Constructor<?> ctor = clazz.getDeclaredConstructor(String.class, BigDecimal.class);
Account a = (Account) ctor.newInstance("SAV2001", new BigDecimal("500000"));
Used by frameworks (Spring, JPA, Jackson) to create objects dynamically. Slower than new.
3. clone()
Account copy = original.clone(); // shallow copy, requires Cloneable
4. Deserialization
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("account.ser"));
Account a = (Account) ois.readObject(); // no constructor called!
Warning: deserialization bypasses the constructor entirely. Security risk with untrusted data.
5. Factory method
public class Account {
public static Account createSavings(String id, BigDecimal balance) {
Account a = new Account(id, balance);
a.type = AccountType.SAVINGS;
return a;
}
}
Account sa = Account.createSavings("SAV2001", new BigDecimal("500000"));
Factory methods can return cached instances, subclasses, or validated objects.
6. Spring DI
@Component
public class AccountService {
// Spring creates this bean via reflection and injects the repository
private final AccountRepository repo;
public AccountService(AccountRepository repo) { this.repo = repo; }
}
What should a senior engineer know?
- Reflection is slow (~10x slower than new) but the JVM caches reflection metadata after first use.
- Deserialization is a security risk. Never deserialize untrusted data. Prefer JSON/Protobuf.
- Record classes can be created with new:
new AccountSummary("SAV2001", balance)– the canonical constructor. - Enum constants cannot be created with new. They are created at class load time.
What are common mistakes?
A common mistake is not understanding the concept fully before using it in production banking applications.
Wrong approach:
package com.bank.service;
public class TransferService {
public void transfer(String fromAccount, String toAccount, double amount) {
// WRONG: using double for money
double balance = getBalance(fromAccount);
balance = balance - amount;
}
private double getBalance(String id) { return 10000.0; }
}
Correct approach:
package com.bank.service;
import java.math.BigDecimal;
public class TransferService {
public void transfer(String fromAccount, String toAccount, BigDecimal amount) {
// CORRECT: using BigDecimal for money
BigDecimal balance = getBalance(fromAccount);
balance = balance.subtract(amount);
}
private BigDecimal getBalance(String id) { return new BigDecimal("10000.00"); }
}
Always use BigDecimal for monetary calculations in banking systems to avoid floating-point precision errors.
Visual Overview
6 ways to create objects: 1. new Account(...) ← most common, compile-time checked 2. Class.forName(...).newInstance() ← reflection, used by frameworks 3. account.clone() ← shallow copy 4. ObjectInputStream.readObject() ← deserialization, bypasses constructor 5. Account.create(...) ← factory method, encapsulates logic 6. Spring @Component ← framework creates via reflection + DI
Key Takeaway
Java has six ways to create objects: new, reflection, clone, deserialization, factory methods, and framework DI. New is the most common and fastest. Reflection is used by frameworks like Spring and JPA. Factory methods encapsulate creation logic. And deserialization bypasses the constructor entirely, which is a security concern.
One sentence to remember: new is the standard, reflection is for frameworks, factory is for encapsulation, and deserialization bypasses the constructor.
---