Concrete Numbers achieves compile-time guarantees for integer logic by combining four powerful mechanisms in the Java language: inheritance, generics (with multiple bounds), sealed types, and automatic code generation. Together, these allow integers and integer ranges to be represented as types, enabling type-level enforcement of numeric constraints.

The range of Concrete Numbers is, of course, limited—not just by practical concerns like binary footprint and class loading, but more directly by the maximum inheritance depth allowed by the Java compiler. In practice, the range is fixed from −1 to 255; sufficient for many real-world use cases involving small, well-defined integer domains.


Inheritance

Each concrete integer in the system — such as Zero, One, Five — is represented by a singleton class that extends the abstract base class ConcreteNumber. These singleton types also implement interfaces from two related hierarchies: AtLeastX and AtMostX for fixed bounds, and the generic interfaces AtLeast<X> and AtMost<X> for expressing type-bounded numeric ranges. For example, the class Five implements both AtLeastFive and AtMostFive, as well as AtLeast<AtMostFive> and AtMost<AtLeastFive>, enabling parameteric type constraints across a broader numeric lattice. Additionally, number classes encode their successor and predecessor relationships using the generic interfaces NPlus1<X> and NMinus1<X>, linking the entire system into a type-level numeric chain. This supports inductive reasoning over numeric types, enabling expressive, compile-time constraints across adjacent values.

/**
 * The concrete number 5
 */
public final class Five extends ConcreteNumber 
    implements AtLeastFive, 
	           AtMostFive, 
			   AtMost<AtLeastFive>, 
			   AtLeast<AtMostFive>, 
			   NMinus1<Six>, 
			   NPlus1<Four> {
				
    public static final Five FIVE = new Five(); 
	
	private Five() { 
		super(5); 
	} 
}
/**
 * An integer no less than 5
 */
public sealed interface AtLeastFive
    extends AtLeastFour
    permits Five, AtLeastSix {
}
/**
 * An integer no greater than 5
 */
public sealed interface AtMostFive
    extends AtMostSix
    permits Five, AtMostFour {
}

The depth of the AtLeastX and AtMostX hierarchies determines the available numeric range. Currently, the Java compiler imposes a limit on inheritance depth of approximately 256 levels, which bounds the range of concrete integers supported at compile time.


Generics & Multiple Bounds

A core strength of Concrete Numbers lies in its use of multiple bounds on generic type parameters. By combining interface constraints like AtLeast<X> and AtMost<X>, it becomes possible to express rich, compile-time verifiable numeric relationships within type signatures.

For example, an interface representing a polygon might enforce that the number of sides is at least three:

public interface Polygon<N extends ConcreteNumber & AtLeastThree> { 
	N numSides(); 
}

And a method might accept an index constrained to a valid numeric subrange derived from N:

public <K extends AtLeastOne & AtMost<? super N>> 
Point vertex(K k);

These constraints are enforced by the compiler, ensuring that numeric assumptions are made explicit and upheld throughout the type system. This use of generics enables precise modeling of discrete numeric domains in code — with no runtime overhead or unchecked casting.


Sealed Types

The Concrete Numbers system uses sealed interfaces and classes to preserve the integrity of its type lattice. Core components — including the abstract base ConcreteNumber and the fixed-bound hierarchies AtMostX and AtLeastX — are sealed, and all concrete number types like Zero, One, Five, etc., are declared final. This ensures that only the known, finite set of types participate in subtype relationships, enabling the compiler to enforce strict type constraints.


Code Generation

All types within the Concrete Numbers system — including the base class ConcreteNumber, the singleton integer types Zero, One, etc., the AtMostX and AtLeastX hierarchies, as well as the generic interfaces AtMost<X>, AtLeast<X>, NMinus1<X>, and NPlus1<X> — are automatically generated. This automation eliminates boilerplate and ensures the system scales naturally with future increases to Java’s inheritance depth limits.

Code generation guarantees that every type relationship is complete, correctly linked, and closed under inheritance — an essential foundation for reliable constraint propagation.

Although Concrete Numbers is auto-generated, it is designed to integrate with a separate hand-written numeric API that defines abstract concepts such as Integer, RationalNumber, and RealNumber. Each concrete number implements Integer, allowing seamless use across the broader numeric system.