Generics
The Problem Generics Solve
Imagine you build a gift box. One day you put a book in it, another day a toy, another day chocolates. Without generics, Java would treat every box the same — you'd put stuff in as Object and have to guess what's inside when you take it out. That's messy and error-prone.
Generics let you create a box and say: "This box is specifically for books." Now Java knows exactly what's inside, catches mistakes at compile time, and you never have to guess.
You've already used generics without realizing it! ArrayList<String> is a generic ArrayList that only holds Strings. The <String> part is the type parameter.
Creating a Generic Class
Generic Methods & Bounded Types
You don't have to make the whole class generic — you can make individual methods generic too. Just put the type parameter before the return type.
Bounded types let you restrict what types are allowed. <T extends Number> means "T can be Integer, Double, Float, etc. — anything that IS-A Number." This lets you use Number methods like .doubleValue() inside your generic code.
Wildcards (?) are used when you want to accept "any type" but don't need to name it. List<?> means "a list of anything." List<? extends Number> means "a list of some Number type."
Generic Methods
Generic Class with Multiple Type Parameters
Box<String> becomes just Box in the compiled code. This is why you can't do new T() or T[] arr = new T[10] — Java doesn't know what T is at runtime!