🧰
OOP

Generics

Type-Safe Reusable Code
💡 Generics एक universal toolbox जैसा है जिसमें तुम label लगा सकते हो कि "इस बार सिर्फ़ screws (Integer) रखूँगा" या "इस बार सिर्फ़ nails (String)" — box वही है, पर अंदर सिर्फ़ एक type की चीज़ जाती है, mix-up नहीं होता।

Generics <T> से हम classes/methods को "किसी भी type के लिए काम करने वाला" बना सकते हैं, बिना अलग-अलग versions लिखे।

Compile-time पर type-safety मिलती है — ग़लत type डालने की कोशिश पर compiler तुरंत error दे देता है, run-time crash से बचा लेता है।

class Box<T> {
  T item;
  void set(T item) { this.item = item; }
  T get() { return item; }
}
Box<String> b = new Box<>();
b.set("Hello");
🧰
Generics एक universal toolbox जैसा है जिसमें तुम label लगा सकते हो कि "इस बार सिर्फ़ screws (Integer) रखूँगा" या "इस बार सिर्फ़ nails (String)" — box वही है, पर अंदर सिर्फ़ एक type की चीज़ जाती है, mix-up नहीं होता।
1 / 4
⚡ झट से Recap
  • <T> से एक ही class कई types के लिए काम करती है
  • Compile-time type safety मिलती है
  • List<String>, Box<Integer> जैसे examples
इस page में (4 subtopics)

सिर्फ़ classes नहीं, individual methods भी generic हो सकते हैं — अपना ख़ुद का type parameter define करके, चाहे class generic ना हो। Method definition में <T> return type से पहले लिखते हैं।

static <T> T firstElement(List<T> list) {
  return list.get(0);
}

<T extends Number> का मतलब है T सिर्फ़ Number या उसकी subclasses (Integer, Double, etc.) हो सकती है — इससे तुम T पर Number के methods (जैसे .doubleValue()) call कर सकते हो, जो वरना allowed नहीं होता (compiler को पता नहीं होता T के पास ये method है या नहीं, जब तक bound ना दिया जाए)।

static <T extends Number> double sum(List<T> list) {
  double total = 0;
  for (T item : list) total += item.doubleValue(); // Number ka method
  return total;
}

? extends Type का मतलब "Type या उसकी कोई subclass" (read-only use के लिए अच्छा — "producer", तुम इसे पढ़ सकते हो लेकिन add नहीं कर सकते क्योंकि compiler exact type नहीं जानता)। ? super Type का मतलब "Type या उसकी कोई superclass" (write के लिए अच्छा — "consumer")। ये "PECS" principle कहलाता है: Producer Extends, Consumer Super।

void printAll(List<? extends Number> list) { // read-only OK
  for (Number n : list) System.out.println(n);
}

Java generics compile-time feature हैं — runtime पर generic type information "erase" (मिटा) हो जाती है, backward compatibility के लिए (पुराना Java code, जो generics से पहले लिखा गया था, बिना modify किए नए JVM पर भी चल सके)। इसी वजह से List<String> और List<Integer> runtime पर same class (List) दिखते हैं, और तुम new T() जैसा direct instantiation नहीं कर सकते (JVM को पता ही नहीं T क्या है runtime पर)।