Generics (Java / Python) and Templates (C++) allow developers to write reusable, type-safe classes, interfaces, and methods that operate across multiple data types without code duplication or manual type casting.
(String) list.get(0)).
ClassCastException — Ensures object structures
strictly contain expected types.
A generic class uses a type parameter placeholder (e.g., T) that is replaced with
a concrete type upon instantiation.
class Box<T> {
private T value;
public void set(T value) { this.value = value; }
public T get() { return value; }
}
public class Main {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
intBox.set(100);
System.out.println(intBox.get()); // 100
Box<String> strBox = new Box<>();
strBox.set("Hello Generics");
System.out.println(strBox.get()); // Hello Generics
}
}
#include <iostream>
#include <string>
using namespace std;
template <typename T>
class Box {
private:
T value;
public:
void set(T value) { this->value = value; }
T get() { return value; }
};
int main() {
Box<int> intBox;
intBox.set(100);
cout << intBox.get() << "\n"; // 100
Box<string> strBox;
strBox.set("Hello Templates");
cout << strBox.get() << "\n"; // Hello Templates
return 0;
}
from typing import TypeVar, Generic
T = TypeVar("T")
class Box(Generic[T]):
def __init__(self) -> None:
self.value: T
def set(self, value: T) -> None:
self.value = value
def get(self) -> T:
return self.value
def main():
int_box = Box[int]()
int_box.set(100)
print(int_box.get()) # 100
str_box = Box[str]()
str_box.set("Hello Generics")
print(str_box.get()) # Hello Generics
if __name__ == "__main__":
main()
You can declare generic methods within non-generic or generic classes. The type parameter is specified before the method return type.
class Printer {
public <T> void printData(T data) {
System.out.println("Data: " + data);
}
}
public class Main {
public static void main(String[] args) {
Printer p = new Printer();
p.printData(100); // Data: 100
p.printData("Generics"); // Data: Generics
p.printData(3.14); // Data: 3.14
}
}
#include <iostream>
#include <string>
using namespace std;
template <typename T>
void printData(T data) {
cout << "Data: " << data << "\n";
}
int main() {
printData(100);
printData(string("Templates"));
printData(3.14);
return 0;
}
from typing import TypeVar
T = TypeVar("T")
def print_data(data: T) -> None:
print("Data:", data)
def main():
print_data(100)
print_data("Generics")
print_data(3.14)
if __name__ == "__main__":
main()
Bounded type parameters restrict acceptable types for generic arguments to specific class hierarchies or interfaces.
<T extends Number> restricts T to
Number or its subclasses.
template <Numeric T> uses concepts
(e.g. std::is_arithmetic_v<T>) to enforce constraints at compile-time.
T = TypeVar("T", bound=Number) restricts static type
checkers like mypy.
class NumericBox<T extends Number> {
private T num;
public NumericBox(T num) { this.num = num; }
public double square() {
return num.doubleValue() * num.doubleValue();
}
}
public class Main {
public static void main(String[] args) {
NumericBox<Integer> intBox = new NumericBox<>(10);
System.out.println(intBox.square()); // 100.0
// Compile-time error!
// NumericBox<String> strBox = new NumericBox<>("Hello");
}
}
#include <iostream>
#include <type_traits>
using namespace std;
// C++20 Concept
template <typename T>
concept Numeric = is_arithmetic_v<T>;
template <Numeric T>
class NumericBox {
private:
T num;
public:
NumericBox(T num) : num(num) {}
double square() { return (double)num * (double)num; }
};
int main() {
NumericBox<int> intBox(10);
cout << intBox.square() << "\n"; // 100.0
// Compile-time error!
// NumericBox<string> strBox("Hello");
return 0;
}
from typing import TypeVar
from numbers import Number
T = TypeVar("T", bound=Number)
def square(num: T) -> float:
return float(num) * float(num)
def main():
print(square(10)) # 100.0
print(square(5.5)) # 30.25
# static type checker flags: square("Hello")
if __name__ == "__main__":
main()
In Java, wildcards (?) handle unknown or variable generic arguments:
? extends T): Allows reading elements
of type T or its subclasses. Restricts adding new elements.
? super T): Allows writing elements of
type T or its superclasses. Restricts safe reading.
In Python, typing helpers like Any, Union, and variance annotations
provide similar static checking flexibility.
Languages handle generic type implementation differently at compile time and runtime:
Object (or bound types). At runtime, Box<Integer> and
Box<String> become the exact same raw class Box.
Box<int> and Box<string>). This guarantees zero
runtime overhead and maximum speed, though it can increase compiled binary size.
mypy, pyright) and IDEs. Python runtime
ignores type parameters and does not enforce type bounds unless explicitly checked at
runtime.
| Aspect | Java | C++ | Python |
|---|---|---|---|
| Implementation | Generics (<T>) |
Templates (template <typename T>) |
Type Hints (TypeVar / Generic[T]) |
| Under the Hood | Type Erasure (replaced with Object at compile-time) |
Template Instantiation (generates machine code per type) | Ignored at runtime (used by static type checkers like mypy) |
| Type Safety | Enforced at compile-time | Enforced at compile-time | Static type checking only (not runtime enforced) |
| Bounded Constraints |
<T extends Class> / Wildcards (? extends,
? super)
|
C++20 Concepts (requires / concept) |
TypeVar("T", bound=Class) |
| Raw Types | Supported (legacy raw List without <T>) |
Not allowed (requires concrete type parameters) | Omitting type hints defaults to dynamic typing |
What is Java Type Erasure?
How do C++ Templates differ from Java Generics at compiled runtime?
Purpose ⇒ Type-safe, reusable classes & methods without code duplication
Syntax ⇒ Java <T> ; C++ template <typename T> ; Python
TypeVar("T")
Java ⇒ <T extends Number> ; Wildcards (? extends T
read-only, ? super T write-only)
C++ ⇒ C++20 Concepts (template <Numeric T> ;
concept Numeric = is_arithmetic_v<T>)
Python ⇒ TypeVar("T", bound=Number) for static type checkers
Java Type Erasure ⇒ Strips <T> at compile-time ; replaces with
Object for JVM backward compatibility
C++ Template Instantiation ⇒ Compiler generates dedicated binary code per type ; maximum performance
Python Static Typing ⇒ Type hints used by mypy/IDEs ; ignored by Python runtime
Primary source: Oracle Java Tutorials — Generics, cppreference — Templates & Python Docs — typing module. Ask me anything that's unclear.
Questions? Ask your agent — you can follow up on any concept, quiz answer, or how this applies to a specific coding problem. Review the Java glossary or syntax quick reference for a compressed overview.