النوع العام هو صنف عام أو واجهة عامة مُعامَلة على الأنواع. وهذا يسمح للمُصرِّف بفرض أمان الأنواع على الصنف أو الواجهة.
تأمّل واجهة Container غير العامة التالية:
class Container {
private Object object;
public void set(Object object) { this.object = object; }
public Object get() { return object; }
}
وبما أنها تقبل أنواع Object وتُرجعها، فإنها تعمل مع أي نوع غير أولي. لكن هذا له ثمن، لأن بعض الكود قد يستدعي get وهو يتوقع قيمًا من نوع Integer، بينما يستدعي كود آخر set مضيفًا قيمًا من نوع String، ما يؤدي إلى استثناء وقت التشغيل.
يكون للصنف العام والواجهة العامة الشكلان التاليان:
class ClassName<T1, T2, ..., Tn> { ... }
interface InterfaceName<T1, T2, ..., Tn> { ... }
قسم معاملات النوع، المحدد بالأقواس الزاوية (<>)، والذي يلي اسم الصنف أو الواجهة، يحدد معاملات النوع (وتسمى أيضًا متغيرات النوع) T1 وT2 و... وTn. ويمكن استخدامها داخل جسم الصنف أو الواجهة للحصول على أمان الأنواع العام.
وهذه هي النسخة العامة من Container:
class Container<E> {
private E object;
public void set(E object) { this.object = object; }
public E get() { return object; }
}
عند الإنشاء، علينا الآن أن نُعلن نوع ما يحمله، وسيفرض المُصرِّف هذا القيد:
// empty <> can infer from context
Container<String> stringContainer = new Container<>();
// compiler knows this is a String, so it is allowed
stringContainer.set("Some string");
// no cast needed, compiler knows it is a String
String result = stringContainer.get();
// this causes a compiler error:
stringContainer.set(42);