Master Java Generics: From Basics to Advanced Customizations
This article explains why Java generics were introduced, outlines their benefits for type safety and code clarity, demonstrates common generic interfaces and collections, dives into usage details such as inheritance and shorthand forms, and shows how to create custom generic classes, methods, and avoid typical pitfalls.
1. Introduction to Generics
Because collections like ArrayList store elements as Object, adding mismatched types can cause runtime type errors; generics were introduced to enforce compile‑time type constraints and improve program robustness.
2. Benefits of Using Generics
Improves program robustness and standardization.
Compile‑time checking prevents illegal element insertion.
Reduces the number of casts, enhancing performance.
Allows class fields, method return types, and parameters to be expressed as placeholders.
3. Common Generic Usages
3.1 Generic Interface
Define an interface with type parameters U and R to enforce method signatures.
interface Im<U,R>{
void hi(R r);
void hello(R r1,R r2,U u1,U u2);
default R method(U u){
return null;
}
}Implementations must use the declared types, otherwise compilation fails.
3.2 Generic Collections
Using generics with HashSet and HashMap to store Student objects eliminates casts and enforces type safety.
HashSet<Student> students = new HashSet<>();
students.add(new Student("Lazy",21));
students.add(new Student("Happy",41));
students.add(new Student("Cute",13));
for (Student s : students){
System.out.println(s);
}
HashMap<String,Student> hm = new HashMap<>();
hm.put("001",new Student("Happy",21));
hm.put("002",new Student("Lazy",32));
hm.put("003",new Student("Cute",43));
Set<Map.Entry<String,Student>> entries = hm.entrySet();
Iterator<Map.Entry<String,Student>> it = entries.iterator();
while(it.hasNext()){
Map.Entry<String,Student> e = it.next();
System.out.println(e.getKey()+" - "+e.getValue());
}The generic K‑V pair in HashMap ensures both key and value types are known, removing the need for manual casting.
4. Details of Generic Usage
4.1 Type Specification in <>
4.2 Inheritance
P<A> ap = new P<A>(new A());
P<A> ap1 = new P<A>(new B()); // B extends A
class A{}
class B extends A{}4.3 Shorthand Form
P<A> ap = new P(new A());5. Custom Generics
5.1 Generic Class Used in Method
public static void main(String[] args){
U<String,Double,Integer> u = new U<>();
u.hi("hello",1.0);
}
class U<X,Y,Z>{
public void hi(X x, Y y){}
}5.2 Generic Method
public static void main(String[] args){
U<String,Double,Integer> u = new U<>();
u.m1("xx",22);
}
class U<X,Y,Z>{
public <X,Y> void m1(X x, Y y){}
}The compiler automatically boxes primitive arguments to match the declared generic types.
5.3 Pitfalls
Generic arrays cannot be created because the runtime component type is unknown (e.g., A[] a = new A[]; is illegal).
Static methods cannot use class‑level generic type parameters because static context is independent of any instance.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
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.
