JavaRush /مدونة جافا /Random-AR /Autoboxing وunboxing في جافا
DSergey_Kh
مستوى

Autoboxing وunboxing في جافا

نشرت في المجموعة
في هذه المقالة سوف نلقي نظرة على ميزة في Java تسمى autoboxing/unboxing . تعد عملية Autoboxing وunboxing بمثابة وظيفة لتحويل الأنواع البدائية إلى أنواع كائنات والعكس صحيح. Autoboxing وunboxing في جافا - 1يتم تنفيذ العملية بأكملها تلقائيًا بواسطة Java Runtime Environment (JRE). ولكن يجب عليك توخي الحذر عند تنفيذ هذه الوظيفة، لأن... يمكن أن يؤثر على أداء البرنامج الخاص بك.

مقدمة

في الإصدارات الأقل من JDK 1.5، لم يكن من السهل تحويل أنواع البيانات البدائية مثل intو charو و floatو doubleإلى فئاتها المجمعة Integer و Character و Float و Double. بدءًا من JDK 5، يتم تنفيذ هذه الوظيفة تلقائيًا، وهي تحويل الأنواع البدائية إلى كائنات مكافئة. تُعرف هذه الخاصية باسم Autoboxing . العملية العكسية، على التوالي، هي Unboxing ، أي. عملية تحويل الكائنات إلى الأنواع البدائية المقابلة لها. نموذج التعليمات البرمجية لـ autoboxing وunboxing موضح أدناه: Autoboxing
Integer integer = 9;
الإخراج من العلبة
int in = 0;
in = new Integer(9);
متى يتم استخدام التعبئة والتفريغ التلقائي؟ يتم استخدام Autoboxing بواسطة مترجم Java في الحالات التالية:
  • عندما يتم تمرير قيمة من النوع البدائي إلى طريقة كمعلمة طريقة، فإنها تتوقع كائنًا من فئة الغلاف المقابلة.
  • عندما يتم تعيين قيمة من النوع البدائي لمتغير من فئة الغلاف المقابلة.
خذ بعين الاعتبار المثال التالي: القائمة 1: رمز بسيط يُظهر التشغيل التلقائي
public int sumEvenNumbers(List<Integer> intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}
قبل الإصدار jdk 1.5، كان من الممكن أن يتسبب الكود أعلاه في حدوث خطأ في الترجمة لأنه لا يمكن تطبيق عامل التشغيل المتبقي % وunary plus += على فئة المجمع. ولكن في الإصدار jdk 1.5 وما فوق، يتم تجميع هذا الرمز بدون أخطاء، وتحويل Integer إلى int. يتم استخدام Unboxing بواسطة مترجم Java بالشروط التالية:
  • عندما يتم تمرير كائن كمعلمة إلى طريقة تتوقع نوعًا بدائيًا مطابقًا.
  • عندما يتم تعيين كائن لمتغير من النوع البدائي المقابل.
خذ بعين الاعتبار المثال التالي: القائمة 2: رمز بسيط يوضح فتح العلبة
import java.util.ArrayList;
import java.util.List;

public class UnboxingCheck {

public static void main(String[] args) {
Integer in = new Integer(-8);

// 1. Распаковка через вызов метода
int absVal = absoluteValue(in);
System.out.println("absolute value of " + in + " = " + absVal);

List<Double> doubleList = new ArrayList<Double>();

// Автоупаковка через вызов метода
doubleList.add(3.1416);

// 2. Распаковка через присвоение
double phi = doubleList.get(0);
System.out.println("phi = " + phi);
}

public static int absoluteValue(int i) {
return (i < 0) ? -i : i;
}
}
يسمح Autoboxing وunboxing للمطور بكتابة تعليمات برمجية يسهل قراءتها وفهمها. يوضح الجدول التالي أنواع البيانات الأولية وكائنات الغلاف المقابلة لها.
أنواع بدائية فئات شل
منطقية منطقية
بايت بايت
شار شخصية
يطفو يطفو
كثافة العمليات عدد صحيح
طويل طويل
قصير قصير
الجدول 1: الأنواع البدائية وفئات التغليف المكافئة مع عوامل المقارنة يمكن استخدام Autoboxing وunboxing مع عوامل المقارنة. يوضح مقتطف الكود التالي كيفية حدوث ذلك: القائمة 3: نموذج التعليمات البرمجية الذي يوضح عملية التشغيل التلقائي وإلغاء التغليف باستخدام عامل مقارنة
public class BoxedComparator {
  public static void main(String[] args) {
      Integer in = new Integer(25);
      if (in < 35)
          System.out.println("Value of int = " + in);
  }
}
التعبئة التلقائية والتفريغ عند التحميل الزائد لطريقة ما يتم إجراء التعبئة التلقائية والتفريغ عند التحميل الزائد لطريقة ما بناءً على القواعد التالية:
  • التوسع "يهزم" التغليف في الحالة التي يكون فيها الاختيار بين التوسع والتعبئة، التوسع هو الأفضل.
القائمة 4: نموذج التعليمات البرمجية الذي يوضح فائدة التحميل الزائد
public class WideBoxed {
  public class WideBoxed {
  static void methodWide(int i) {
       System.out.println("int");
   }

  static void methodWide( Integer i ) {
      System.out.println("Integer");
  }

  public static void main(String[] args) {
      short shVal = 25;
      methodWide(shVal);
  }
 }
}
مخرجات البرنامج - النوعint
  • يتفوق التوسيع على عدد متغير من الوسائط في الحالة التي يصبح فيها الاختيار بين التوسيع وعدد متغير من الوسائط، يكون التوسيع هو الأفضل.
القائمة 5: نموذج التعليمات البرمجية الذي يوضح فائدة التحميل الزائد
public class WideVarArgs {

    static void methodWideVar(int i1, int i2) {
      System.out.println("int int");
    }

    static void methodWideVar(Integer... i) {
       System.out.println("Integers");
    }

   public static void main( String[] args) {
       short shVal1 = 25;
      short shVal2 = 35;
     methodWideVar( shVal1, shVal2);
   }
  }
  • التعبئة تتفوق على عدد متغير من الوسائط في الحالة التي يصبح فيها الاختيار بين التعبئة وعدد متغير من الوسائط، تكون التعبئة هي الأفضل.
القائمة 6: نموذج التعليمات البرمجية الذي يوضح فائدة التحميل الزائد
public class BoxVarargs {
     static void methodBoxVar(Integer in) {
         System.out.println("Integer");
     }

     static void methodBoxVar(Integer... i) {
         System.out.println("Integers");
     }
     public static void main(String[] args) {
         int intVal1 = 25;
         methodBoxVar(intVal1);
    }
}
يجب أن تضع الأمور التالية في الاعتبار أثناء استخدام التعبئة التلقائية: كما نعلم، كل ميزة جيدة لها عيب. التعبئة والتغليف التلقائي ليست استثناء في هذا الصدد. بعض الملاحظات المهمة التي يجب على المطور مراعاتها عند استخدام هذه الميزة:
  • يمكن أن تكون مقارنة الكائنات مع ==عامل التشغيل ' ' أمرًا مربكًا، حيث يمكن تطبيقه على الأنواع والكائنات البدائية. عندما يتم تطبيق هذا العامل على الكائنات، فإنه في الواقع يقارن المراجع إلى الكائنات، وليس الكائنات نفسها.
القائمة 7: نموذج التعليمات البرمجية الذي يوضح المقارنة.
public class Comparator {
   public static void main(String[] args) {
     Integer istInt = new Integer(1);
       Integer secondInt = new Integer(1);

       if (istInt == secondInt) {
         System.out.println("both one are equal");

       } else {
          System.out.println("Both one are not equal");
      }
   }
}
  • خلط الكائنات والأنواع البدائية مع عوامل المساواة والعلائقية. إذا قارنا نوعًا بدائيًا بكائن ما، فسيتم إلغاء تحديد الكائن، مما قد يؤدي إلى رمي NullPointerExceptionالكائن null.
  • التخزين المؤقت للكائن. تقوم الطريقة valueOf()بإنشاء حاوية من الكائنات البدائية التي تقوم بتخزينها مؤقتًا. نظرًا لأن القيم مخزنة مؤقتًا في النطاق من -128 إلى 127، فقد تتصرف هذه الكائنات المخزنة مؤقتًا بشكل مختلف.
  • انحطاط الأداء. تؤدي عملية Autoboxing أو unboxing إلى انخفاض أداء التطبيق لأنها تنشئ كائنًا غير مرغوب فيه يفرض على أداة تجميع البيانات المهملة العمل بشكل متكرر أكثر.
مساوئ AutoBoxing على الرغم من أن AutoBoxing له عدد من المزايا، إلا أنه يحتوي على العيوب التالية: القائمة 8: نموذج التعليمات البرمجية الذي يوضح مشكلة الأداء.
public int sumEvenNumbers(List intList) {
          int sum = 0;
          for (Integer i : intList) {
              if (i % 2 == 0) {
                  sum += i;
              }
          }
         return sum;
   }
في هذا القسم من التعليمات البرمجية، sum +=i سيتم توسيعه إلى sum = sum + i. بدءًا من +عامل التشغيل ' '، يبدأ JVM في فتح العلبة لأنه +لا يمكن تطبيق عامل التشغيل ' ' على كائن عدد صحيح. ومن ثم يتم تعبئة النتيجة تلقائيًا مرة أخرى. قبل JDK 1.5، intكانت أنواع البيانات والأعداد الصحيحة مختلفة. في حالة التحميل الزائد للطريقة، تم استخدام هذين النوعين دون مشاكل. ومع ظهور التعبئة/التفريغ التلقائي، أصبح هذا الأمر أكثر صعوبة. مثال على ذلك هو الطريقة المحملة بشكل زائد remove()في ArrayList. يحتوي الفصل ArrayListعلى طريقتين للحذف - remove(index)و remove(object). في هذه الحالة، لن يحدث تحميل زائد للطريقة وسيتم استدعاء الطريقة المقابلة باستخدام المعلمات المناسبة.

خاتمة

Autoboxing هي آلية لتحويل أنواع البيانات البدائية ضمنيًا إلى فئات مجمعة (كائنات) مقابلة. يستخدم المترجم طريقة valueOf()لتحويل الأنواع البدائية إلى كائنات، والطرق وما إلى IntValue()ذلك doubleValue()للحصول على الأنواع البدائية للكائن. يقوم Autoboxing بتحويل النوع المنطقي booleanإلى Boolean، byteإلى Byte، charإلى Character، floatإلى Float، intإلى Integer، longإلى Long، shortإلى Short. يحدث التفريغ في الاتجاه المعاكس. المقالة الأصلية
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION