تعد Java Generics (Generics) ميزة جديدة تم تقديمها في JDK5 والتي تسمح باستخدام معلمات النوع (معلمة النوع) عند تحديد الفئات والواجهات. يتم استبدال معلمات النوع المعلنة بأنواع محددة عند استخدامها. أهم تطبيق للأدوية العامة الآن هو في إطار عمل فئة المجموعة الجديد في JDK5، حيث يتم استخدام الخريطة والقائمة. المزايا واضحة بذاتها، يمكننا توسيع المزيد من الفئات أفقيًا، والعيوب هي في الواقع مزاياها، لأنه عندما نستخدم فئات عامة، يجب أن نكون واضحين جدًا بشأن الغرض من الكود الخاص بنا ولا يمكننا استخدام الأخطاء.
الطبقة العامة الأساسية
انسخ رمز الكود كما يلي:
الحزمة com.garinzhang.javabase.generic.e1؛
/**
* الفئة العامة الأساسية، يتم تحديد النوع بنفسك
* @ المؤلف جارين تشانغ
*
* @param <T>
*/
نقطة الطبقة العامة<T> {
خاص T فار؛
عامة T getVar () {
العودة فار؛
}
مجموعة الفراغ العامة (T var) {
this.var = var;
}
}
الحزمة com.garinzhang.javabase.generic.e1؛
مثال عام للفئة العامة {
/**
* @param args
*/
public static void main(String[] args) {
Point<String> p = new Point<String> ();
p.setVar("المبرمج");
System.out.println(p.getVar());
}
}
أنواع عامة متعددة
انسخ رمز الكود كما يلي:
الحزمة com.garinzhang.javabase.generic.e2؛
/**
* الأنواع العامة المتعددة بشكل عام، من الأفضل استخدام الحروف القريبة من T، مثل S، R، إلخ.
* @ المؤلف جارين تشانغ
*
* @param <T>
* @param <S>
*/
المفكرة العامة <T، S> {
مفتاح T الخاص؛
قيمة S الخاصة؛
public T getKey() {
إرجاع هذا.مفتاح؛
}
عامة S getValue() {
إرجاع هذه القيمة؛
}
مفتاح مجموعة الفراغ العام (مفتاح T) {
this.key = key;
}
مجموعة الفراغ العام (قيمة S) {
this.value = value;
}
}
الحزمة com.garinzhang.javabase.generic.e2؛
مثال عام للفئة العامة {
/**
* @param args
*/
public static void main(String[] args) {
Notepad<String, Integer> p = new Notepad<String, Integer> ();
p.setKey("المبرمج");
p.setValue(99999);
System.out.println("مفتاح:" + p.getKey());
System.out.println("القيمة: " + p.getValue());
}
}
استخدم حرف البدل "؟" في معلمات الطريقة
انسخ رمز الكود كما يلي:
الحزمة com.garinzhang.javabase.generic.e3؛
/**
* مفتاح هذا المثال موجود في الطريقة الرئيسية
* @ المؤلف جارين تشانغ
*
* @param <T>
*/
معلومات الفئة العامة<T> {
مفتاح T الخاص؛
public T getKey() {
إرجاع هذا.مفتاح؛
}
مفتاح مجموعة الفراغ العام (مفتاح T) {
this.key = key;
}
@تجاوز
سلسلة عامة إلى سلسلة () {
إرجاع this.key.toString();
}
}
الحزمة com.garinzhang.javabase.generic.e3؛
/**
* استخدم أحرف البدل في معلمات الطريقة
* @ المؤلف جارين تشانغ
*
*/
مثال عام للفئة العامة {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> i = new Info<String>();
i.setKey("المبرمج");
متعة (ط)؛
Info<Integer> j = معلومات جديدة<Integer>();
j.setKey(9999);
متعة (ي)؛
}
متعة الفراغ الثابت العام (معلومات <؟> درجة الحرارة) {
System.out.println("المحتوى:" + درجة الحرارة);
}
}
فشل التحول التصاعدي
انسخ رمز الكود كما يلي:
الحزمة com.garinzhang.javabase.generic.e4؛
/**
* مفتاح هذا المثال موجود في الطريقة الرئيسية
* @ المؤلف جارين تشانغ
*
* @param <T>
*/
معلومات الفئة العامة<T> {
مفتاح T الخاص؛
public T getKey() {
إرجاع هذا.مفتاح؛
}
مفتاح مجموعة الفراغ العام (مفتاح T) {
this.key = key;
}
@تجاوز
سلسلة عامة إلى سلسلة () {
إرجاع this.key.toString();
}
}
الحزمة com.garinzhang.javabase.generic.e4؛
مثال عام للفئة العامة {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> strEg = new Info<String>();
معلومات<Object> objEg;
// خطأ في الترجمة "النوع غير متطابق: لا يمكن التحويل من المعلومات <سلسلة> إلى المعلومات <الكائن>"
// فشل الإرسال، سلسلة -> كائن
// objEg = strEg;
}
}
استخدام الأدوية العامة في الواجهات
انسخ رمز الكود كما يلي:
الحزمة com.garinzhang.javabase.generic.e5؛
/**
* مفتاح هذا المثال موجود في الطريقة الرئيسية
* @ المؤلف جارين تشانغ
*
* @param <T>
*/
معلومات الواجهة<T> {
public T getVar();
}
الحزمة com.garinzhang.javabase.generic.e5؛
/**
* فئة عامة
* @ المؤلف جارين تشانغ
*
* @param <T>
*/
الطبقة العامة InfoImpl<T> تنفذ المعلومات<T> {
خاص T فار؛
معلومات عامة (T فار) {
this.setVar(var);
}
مجموعة الفراغ العامة (T var) {
this.var = var;
}
public T getVar() {
إرجاع هذا.var;
}
}
الحزمة com.garinzhang.javabase.generic.e5؛
/**
* فئة غير عامة
* @ المؤلف جارين تشانغ
*
* @param <T>
*/
الطبقة العامة InfoImpl1 تنفذ المعلومات<String> {
سلسلة خاصة فار؛
معلومات عامة Impl1(سلسلة فار) {
this.setVar(var);
}
مجموعة الفراغ العامة (سلسلة فار) {
this.var = var;
}
سلسلة عامة getVar () {
إرجاع هذا.var;
}
}
الحزمة com.garinzhang.javabase.generic.e5؛
مثال عام للفئة العامة {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> strEg = new InfoImpl<String>("coder");
System.out.println("المحتوى: " + strEg.getVar());
Info<String> strEg1 = new InfoImpl1("coder1");
System.out.println("المحتوى: " + strEg1.getVar());
}
}
أحرف البدل واستخدام الامتدادات والسوبر
انسخ رمز الكود كما يلي:
الحزمة com.garinzhang.javabase.generic.e6;
/**
* مفتاح هذا المثال موجود في الطريقة الرئيسية
* @ المؤلف جارين تشانغ
*
* @param <T>
*/
معلومات الفئة العامة<T> {
مفتاح T الخاص؛
public T getKey() {
إرجاع هذا.مفتاح؛
}
مفتاح مجموعة الفراغ العام (مفتاح T) {
this.key = key;
}
@تجاوز
سلسلة عامة إلى سلسلة () {
إرجاع this.key.toString();
}
}
الحزمة com.garinzhang.javabase.generic.e6;
مثال عام للفئة العامة {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> strEg = new Info<String>();
strEg.setKey("coder");
// خطأ في الترجمة "الطريقة fun(Info<? Extends Number>) في النوع GenericExample غير قابلة للتطبيق على الوسائط (Info<String>)"
// upTypeLimit(i);
// استخدم أنواع الأعداد الصحيحة أو الأرقام.
Info<Integer> intEg = new Info<Integer>();
intEg.setKey(9999);
upTypeLimit(intEg);
// خطأ في الترجمة "الطريقة downTypeLimit(Info<? super String>) في النوع GenericExample غير قابلة للتطبيق على الوسائط (Info<Integer>)"
// downTypeLimit(intEg);
// نظرًا لاستخدام super، يمكن لـ downTypeLimit تلقي السلسلة نفسها والكائن فقط
// تم التحقق من علاقة وراثة السلسلة، ولم يتم توريث أي فئات أخرى، فقط الكائن
downTypeLimit(strEg);
Info<Object> objEg = new Info<Object>();
objEg.setKey(999);
downTypeLimit(objEg);
}
/**
* يمثل <? Extends T> الحد الأعلى للنوع، مما يشير إلى أن النوع ذو المعلمات قد يكون T أو فئة فرعية من T
* @param temp
*/
public static void upTypeLimit(Info<? Extends Number> temp) {
System.out.println("المحتوى:" + درجة الحرارة);
}
/**
* <? super T> يمثل الحد الأدنى للنوع (يسمى مؤهل النوع الفائق في Java Core)، مما يشير إلى أن النوع ذو المعلمات هو النوع الفائق (النوع الأصلي) من هذا النوع، حتى الكائن
* في هذا المثال، يعني ذلك أن T يمكن أن يكون كائنًا أو سلسلة فقط، لأن السلسلة ترث فقط من الكائن
* @param temp
*/
public static void downTypeLimit(Info<? super String> temp) {
System.out.println("المحتوى:" + درجة الحرارة);
}
}
الأدوية العامة للطريقة، الأدوية العامة المتعددة في الطريقة
انسخ رمز الكود كما يلي:
الحزمة com.garinzhang.javabase.generic.e7؛
/**
* طريقة عامة، عامة متعددة في الطريقة
* @ المؤلف جارين تشانغ
*
* @param <T>
*/
معلومات الفئة العامة {
/**
* التنسيق: تعديل الطريقة <قائمة الأنواع المفصولة بفواصل> اسم طريقة نوع قيمة الإرجاع (قائمة المعلمات)
* على سبيل المثال: عامة <T, S> T fun(T t, S s)
* @param t
* @param s
* @يعود
*/
عامة <T, S> T fun(T t, S s) {
System.out.println(s.toString());
العودة ر؛
}
}
الحزمة com.garinzhang.javabase.generic.e7؛
مثال عام للفئة العامة {
/**
* @param args
*/
public static void main(String[] args) {
معلومات المعلومات = معلومات جديدة ()؛
String str = info.fun("coder"، "طباعة المعلمة العامة الثانية");
System.out.println(str);
int i = info.fun(30, "اطبع المعلمة الثانية مرة أخرى");
System.out.println(i);
}
}
يتم تحديد النوع العام الذي تم تمريره أو إرجاعه في الطريقة من خلال نوع المعلمة الذي تم تعيينه عند استدعاء الطريقة.
انسخ رمز الكود كما يلي:
الحزمة com.garinzhang.javabase.generic.e8؛
/**
* يمتد
* @ المؤلف جارين تشانغ
*
* @param <T>
*/
معلومات الفئة العامة <T يمتد الرقم> {
خاص T فار؛
public T getVar() {
إرجاع هذا.var;
}
مجموعة الفراغ العامة (T var) {
this.var = var;
}
@تجاوز
سلسلة عامة إلى سلسلة () {
إرجاع this.var.toString();
}
}
الحزمة com.garinzhang.javabase.generic.e8؛
مثال عام للفئة العامة {
/**
* @param args
*/
public static void main(String[] args) {
Info<Integer> intEg = fun(30); // تم تحديد النوع هنا على أنه عدد صحيح
System.out.println(intEg.getVar());
}
/**
* يتم تحديد النوع العام الذي تم تمريره أو إرجاعه في الطريقة من خلال نوع المعلمة الذي تم تعيينه عند استدعاء الطريقة.
* @param بارام
* @يعود
*/
ثابت عام <T يمتد الرقم> معلومات <T> متعة (T بارام) {
Info<T> temp = new Info<T>();
temp.setVar(param);
درجة حرارة العودة؛
}
}
اجعل نوعي المعلمات اللتين تم تمريرهما في الطريقة متسقين
انسخ رمز الكود كما يلي:
الحزمة com.garinzhang.javabase.generic.e9;
/**
* عرض الرئيسي
* @ المؤلف جارين تشانغ
*
* @param <T>
*/
معلومات الفئة العامة<T> {
خاص T فار؛
public T getVar() {
إرجاع هذا.var;
}
مجموعة الفراغ العامة (T var) {
this.var = var;
}
@تجاوز
سلسلة عامة إلى سلسلة () {
إرجاع this.var.toString();
}
}
الحزمة com.garinzhang.javabase.generic.e9;
مثال عام للفئة العامة {
/**
* @param args
*/
public static void main(String[] args) {
Info<String> i1 = new Info<String>();
i1.setVar("مرحبًا");
Info<String> i2 = new Info<String>();
i2.setVar("المبرمج");
Info<Integer> i3 = new Info<Integer>();
i3.setVar(999);
إضافة(i1, i2);
// خطأ في الترجمة "طريقة إضافة (Info<T>، Info<T>) في النوع GenericExample غير قابلة للتطبيق على الوسائط (Info<String>، Info<Integer>)"
// أضف (i1، i3)؛
}
/**
* يجب أن يكون نوعا المعلمة اللذان تم تمريرهما في الطريقة متسقين
* @param بارام
* @يعود
*/
إضافة ثابتة عامة <T> باطلة (Info<T> i1, Info<T> i2) {
System.out.println(i1.getVar() + ): "+ i2.getVar());
}
}
الجينات، المعلمات المتغيرة، تشبه كائن الوسائط في JavaScript
انسخ رمز الكود كما يلي:
الحزمة com.garinzhang.javabase.generic.e10؛
مثال عام للفئة العامة {
/**
* @param args
*/
public static void main(String[] args) {
عدد صحيح i[] = fun(1, 2, 3, 4, 5, 6);
fun2(i);
}
عامة ثابتة <T> T[] fun(T...arg) {
وسيطة العودة؛
}
عامة ثابتة <T> باطلة fun2(T param[]) {
System.out.println("مصفوفة عامة:");
ل(تي تي : بارام) {
System.out.println(t + "،");
}
}
}
التداخل العام: استخدم الفئات العامة كمعلمات؛ لتحديد قيمة الإرجاع بناءً على نوع قيمة الإرجاع
انسخ رمز الكود كما يلي:
الحزمة com.garinzhang.javabase.generic.e11؛
/**
* يقبل نوعين عامين
* @ المؤلف جارين تشانغ
*
* @param <T>
*/
معلومات الفئة العامة<T, V> {
خاص T فار؛
قيمة V الخاصة؛
عامة T getVar () {
إرجاع هذا.var;
}
مجموعة الفراغ العامة (T var) {
this.var = var;
}
العامة V getValue(){
إرجاع هذه القيمة؛
}
مجموعة الفراغ العام (قيمة V) {
this.value = value;
}
@تجاوز
سلسلة عامة إلى سلسلة () {
إرجاع this.var.toString();
}
}
الحزمة com.garinzhang.javabase.generic.e11؛
/**
* يقبل نوعًا عامًا واحدًا
* @ المؤلف جارين تشانغ
*
* @param <T>
*/
العرض التوضيحي للفئة العامة<S> {
معلومات S الخاصة؛
العرض التوضيحي العام (معلومات S) {
this.setInfo(info);
}
مجموعة الفراغ العام (معلومات S) {
this.info = info;
}
عامة S getInfo () {
إرجاع هذه المعلومات؛
}
}
الحزمة com.garinzhang.javabase.generic.e11؛
import java.util.List;
import com.google.common.collect.Lists;
مثال عام للفئة العامة {
/**
* @param args
*/
public static void main(String[] args) {
Demo<Info<String, Integer>> d;
معلومات <سلسلة، عدد صحيح> i؛
i = new Info<String, Integer>();
i.setVar("المبرمج");
i.setValue(999);
d = new Demo<Info<String,Integer>>(i);
System.out.println("المحتوى: " + d.getInfo().getVar());
System.out.println("المحتوى: " + d.getInfo().getValue());
System.out.println(query(1, 2, 3, 4, 5).toString()); // [1, 2, 3, 4, 5]
// تحذير "أمان النوع: تم إنشاء مصفوفة عامة من Object&Comparable<?>&Serializable لمعلمة varargs"
System.out.println(query(1, 2, 3, "StringType").toString()); // [1, 2, 3, StringType]
System.out.println(query("I"، "am"، "a"، "coder").toString());// [أنا، مبرمج]
List<String> list = Lists.newArrayList("I"، "am"، "a"، "coder");
System.out.println(list.toString()); // [أنا مبرمج]
}
/**
* تحديد النوع العام من خلال القيمة المرجعة، يتم إنشاء نوع قيمة الإرجاع في هذه الطريقة تلقائيًا من خلال تعريف الطريقة.
* @عناصرparam
* @يعود
*/
قائمة <E> ثابتة عامة <E> استعلام (E... عناصر) {
// https://github.com/exitsoft/exit-web-framework/commit/1d2f1098a2a4b6abab175b793e2308aa8bd0ea16.
//استيراد com.google.common.collect.Lists;
// <التبعية>
// <groupId>com.google.guava</groupId>
// <artifactId>الجوافة</artifactId>
// <version>16.0.1</version>
// </التبعية>
return Lists.newArrayList(elements);
}
}