Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A generic constructor is a constructor that declares its own formal type parameters, distinct from any type parameters declared by the enclosing class. This allows the constructor to enforce type constraints and perform type inference specifically for the instantiation process, regardless of whether the enclosing class itself is generic or non-generic.

Syntax

The type parameter section, enclosed in angle brackets (<>), must precede the constructor’s name.
public class ClassName {
    // <T> is the formal type parameter of the constructor
    public <T> ClassName(T parameter) {
        // Constructor implementation
    }
}

Core Mechanics

1. Independence from Class Generics

A generic constructor’s type parameters are scoped strictly to the constructor. If the enclosing class is also generic, the constructor can declare type parameters that are entirely independent of the class-level type parameters.
public class Container<T> {
    private T item;

    // 'T' is the class type parameter.
    // 'E' is the constructor type parameter.
    public <E extends Number> Container(T item, E numericMetadata) {
        this.item = item;
        System.out.println(numericMetadata.doubleValue());
    }
}

2. Type Inference

When a generic constructor is invoked, the Java compiler typically infers the type arguments based on the actual arguments passed to the constructor.
public class Processor {
    public <T> Processor(T input) {
        System.out.println(input.getClass().getName());
    }
}

// The compiler infers T as java.lang.Integer
Processor p1 = new Processor(100); 

// The compiler infers T as java.lang.String
Processor p2 = new Processor("Data"); 

3. Explicit Type Witness

If the compiler cannot infer the type, or if you need to enforce a specific type hierarchy, you can provide an explicit type witness. The type witness is placed in angle brackets immediately before the class name in the new expression.
// Explicitly defining T as Number, rather than letting it default to Integer
Processor p3 = new <Number>Processor(100);

Bounded Type Parameters in Constructors

Generic constructors support bounded type parameters using the extends keyword to restrict the types that can be passed during instantiation. Multiple bounds can be specified using the & operator.
public class Validator {
    // T must be a subclass of Number and implement Comparable
    public <T extends Number & Comparable<T>> Validator(T value) {
        // Implementation
    }
}

Interaction with the Diamond Operator

When instantiating a generic class that also has a generic constructor, the syntax must accommodate both the class type arguments and the constructor type arguments. If you use an explicit type witness for the constructor, you cannot use the diamond operator (<>) for the class type parameters; both must be explicitly declared.
public class Wrapper<C> {
    public <M> Wrapper(C content, M metadata) {
        // Implementation
    }
}

// Standard inference for both class (String) and constructor (Integer)
Wrapper<String> w1 = new Wrapper<>("Text", 42);

// Explicit type witness for constructor requires explicit class type arguments
Wrapper<String> w2 = new <Number>Wrapper<String>("Text", 42); 

// ILLEGAL: Cannot use diamond operator when explicitly passing constructor type arguments
// Wrapper<String> w3 = new <Number>Wrapper<>("Text", 42); // Compilation Error
Master Java with Deep Grasping Methodology!Learn More