Mastering Java Constructors and Design Patterns: From Implicit to Singleton
This article provides a comprehensive guide to Java object creation, covering implicit, no‑argument, and argument constructors, initialization blocks, static initialization, default value guarantees, visibility rules, garbage collection, finalizers, and common construction patterns such as singleton, helper, factory, and dependency injection.
1. Introduction
Java, created by Sun Microsystems in 1995, is one of the most widely used general‑purpose programming languages. Its powerful libraries, runtime, simple syntax, platform independence (Write Once, Run Anywhere), and strong community make it popular among developers.
This series assumes basic Java knowledge and aims to elevate your skills with advanced concepts, using Java 7 and Java 8 syntax.
2. Instance Construction
Java is an object‑oriented language, so creating new class instances is fundamental. Constructors play a central role, and Java offers several ways to define them.
2.1 Implicit Constructor
A class without an explicit constructor still receives a default no‑argument constructor generated by the compiler.
package com.javacodegeeks.advanced.construction;
public class NoConstructor {
}Creating an instance invokes this implicit constructor:
final NoConstructor noConstructorInstance = new NoConstructor();2.2 No‑Argument Constructor
Explicitly defining a no‑argument constructor is the simplest way to let the compiler generate the default behavior.
package com.javacodegeeks.advanced.construction;
public class NoArgConstructor {
public NoArgConstructor() {
// Constructor body here
}
}Instantiating the class calls this constructor:
final NoArgConstructor noArgConstructor = new NoArgConstructor();2.3 Constructor with Arguments
Parameterized constructors allow passing values during object creation.
package com.javacodegeeks.advanced.construction;
public class ConstructorWithArguments {
public ConstructorWithArguments(final String arg1, final String arg2) {
// Constructor body here
}
}Both arguments must be supplied when using new:
final ConstructorWithArguments constructorWithArguments = new ConstructorWithArguments("arg1", "arg2");Constructors can call each other using this, reducing code duplication and providing a single initialization entry point.
public ConstructorWithArguments(final String arg1) {
this(arg1, null);
}2.4 Initialization Blocks
Java also supports instance initialization blocks, which run before any constructor.
package com.javacodegeeks.advanced.construction;
public class InitializationBlock {
{
// initialization code here
}
}Multiple blocks execute in the order they appear.
package com.javacodegeeks.advanced.construction;
public class InitializationBlocks {
{
// first block
}
{
// second block
}
}2.5 Construction Guarantee
Java automatically initializes fields to default values (e.g., false for booleans, 0 for numeric types, null for object references).
Example demonstrating default values:
package com.javacodegeeks.advanced.construction;
public class InitializationWithDefaults {
private boolean booleanMember;
private byte byteMember;
private short shortMember;
private int intMember;
private long longMember;
private char charMember;
private float floatMember;
private double doubleMember;
private Object referenceMember;
public InitializationWithDefaults() {
System.out.println("booleanMember = " + booleanMember);
System.out.println("byteMember = " + byteMember);
System.out.println("shortMember = " + shortMember);
System.out.println("intMember = " + intMember);
System.out.println("longMember = " + longMember);
System.out.println("charMember = " + charMember);
System.out.println("floatMember = " + floatMember);
System.out.println("doubleMember = " + doubleMember);
System.out.println("referenceMember = " + referenceMember);
}
} final InitializationWithDefaults initializationWithDefaults = new InitializationWithDefaults();Output shows the default values:
booleanMember = false
byteMember = 0
shortMember = 0
intMember = 0
longMember = 0
charMember = 0
floatMember = 0.0
doubleMember = 0.0
referenceMember = null2.6 Visibility
Constructors follow Java's visibility rules and can be declared public, protected, private, or package‑private to control access.
2.7 Garbage Collection
The JVM automatically reclaims memory of objects that are no longer reachable. Java’s generational GC assumes most objects become unreachable shortly after creation, but long‑lived objects can fill the old generation and trigger costly stop‑the‑world collections.
2.8 Finalizers
Finalizers resemble destructors but are generally discouraged due to unpredictability and performance issues. Since Java 7, try‑with‑resources and the AutoCloseable interface provide a safer alternative.
try (final InputStream in = Files.newInputStream(path)) {
// code here
}3. Static Initialization
Static initialization blocks run once when the class is first loaded.
package com.javacodegeeks.advanced.construction;
public class StaticInitializationBlock {
static {
// static initialization code here
}
}Multiple static blocks execute in the order they appear, and the JVM guarantees thread‑safe execution.
package com.javacodegeeks.advanced.construction;
public class StaticInitializationBlocks {
static {
// first static block
}
static {
// second static block
}
}4. Construction Patterns
Common patterns for object creation include Singleton, Helper/Utility classes, Factory, and Dependency Injection.
4.1 Singleton
Ensures only one instance of a class exists. Naïve implementation is not thread‑safe.
package com.javacodegeeks.advanced.construction.patterns;
public class NaiveSingleton {
private static NaiveSingleton instance;
private NaiveSingleton() {}
public static NaiveSingleton getInstance() {
if (instance == null) {
instance = new NaiveSingleton();
}
return instance;
}
}Eager (thread‑safe) version uses a static final field.
package com.javacodegeeks.advanced.construction.patterns;
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}Lazy initialization with synchronization avoids early resource allocation but may reduce concurrency.
package com.javacodegeeks.advanced.construction.patterns;
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}4.2 Utility/Helper Class
Non‑instantiable classes that expose static methods.
package com.javacodegeeks.advanced.construction.patterns;
public final class HelperClass {
private HelperClass() {}
public static void helperMethod1() {
// method body
}
public static void helperMethod2() {
// method body
}
}4.3 Factory Pattern
Encapsulates object creation. Simple static factory method example:
package com.javacodegeeks.advanced.construction.patterns;
public class Book {
private Book(final String title) {}
public static Book newBook(final String title) {
return new Book(title);
}
}Interface‑based factories allow multiple implementations.
public interface BookFactory {
Book newBook();
}
public class Library implements BookFactory {
@Override
public Book newBook() {
return new PaperBook();
}
}
public class KindleLibrary implements BookFactory {
@Override
public Book newBook() {
return new KindleBook();
}
}4.4 Dependency Injection
Dependencies should be supplied externally (e.g., via constructors) rather than created inside the class, improving testability and flexibility.
package com.javacodegeeks.advanced.construction.patterns;
public class Dependant {
private final DateFormat format;
public Dependant(final DateFormat format) {
this.format = format;
}
public String format(final Date date) {
return format.format(date);
}
}The article continues with further exploration of the Object class methods such as equals, hashCode, toString, and clone.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
