سؤال

رأيت هذا في إجابة على سؤال آخر, في إشارة إلى القصور جافا المواصفات:

هناك المزيد من أوجه القصور هذه هي خفية الموضوع.تحقق هذا من:

public class methodOverloading{
     public static void hello(Integer x){
          System.out.println("Integer");
     }

     public static void hello(long x){
          System.out.println("long");
     }

     public static void main(String[] args){
         int i = 5;
         hello(i);
     }
}

هنا "طويلة" سيكون المطبوعة (لم أتحقق بنفسي) ، لأن يختار المترجم في الاتساع أكثر السيارات-الملاكمة.كن حذرا عند استخدام السيارات الملاكمة أو لا تستخدم على الإطلاق!

نحن على يقين من أن هذا هو في الواقع مثال على الاتساع بدلا من autoboxing, أم هو شيء آخر تماما ؟

على بلدي الأولية المسح الضوئي ، أنا أتفق مع بيان أن المخرجات ستكون "طويلة" على أساس i أن أعلنت بأنها بدائية وليس كائن.ومع ذلك ، إذا قمت بتغيير

hello(long x)

إلى

hello(Long x)

إخراج طباعة "صحيح"

ما يحدث في الواقع هنا ؟ أنا لا أعرف شيئا عن المجمعين/بايت كود مترجمين للغة جافا...

هل كانت مفيدة؟

المحلول

في الحالة الأولى يجب تحويل اتساع يحدث.هذا يمكن أن يكون عندما انظر runinng على "javap" فائدة البرنامج (المدرجة w/ JDK) على تجميع الصف:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_ 5
   1:   istore_ 1
   2:   iload_ 1
   3:   i2l
   4:   invokestatic    #6; //Method hello:(J)V
   7:   return

}

من الواضح أنك ترى I2L ، وهو ذاكري من أجل توسيع عدد صحيح إلى طويلة بايت كود التعليمات.انظر المرجع هنا.

و في حالة أخرى ، استبدال "طويلة x" مع "كائن طويل x" التوقيع سيكون لديك هذا الرمز في الأسلوب الرئيسي:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_ 5
   1:   istore_ 1
   2:   iload_ 1
   3:   invokestatic    #6; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   6:   invokestatic    #7; //Method hello:(Ljava/lang/Integer;)V
   9:   return

}

لذلك ترى مترجم خلقت التعليمات صحيح.valueOf(الباحث) ، إلى مربع بدائية داخل المجمع.

نصائح أخرى

نعم هو محاولة بها في الاختبار.سترى "طويلة" المطبوعة.أنها آخذة في الاتساع بسبب جافا سيتم اختيار توسيع الباحث إلى فترة طويلة قبل أن يختار autobox إلى عدد صحيح ، لذلك أهلا(طويلة) الطريقة المختارة ليتم استدعاؤها.

تحرير: المشاركة الأصلية المشار إليها.

آخر تحرير:السبب الثاني خيار الطباعة صحيح لأنه لا يوجد "توسيع" إلى أكبر بدائية كخيار ، لذلك يجب مربع عنه ، وبالتالي عدد صحيح هو الخيار الوحيد.وعلاوة على ذلك, جافا فقط autobox إلى النوع الأصلي ، لذا فإنه يعطي خطأ المترجم إذا ترك مرحبا(طويلة) و إزالة مرحبا(صحيح).

آخر الشيء المثير للاهتمام في هذا المثال هو الأسلوب الحمولة الزائدة.مزيج من نوع توسيع وطريقة إثقال العمل فقط لأن المترجم له إلى اتخاذ قرار من الطريقة التي تختار.النظر في المثال التالي:

public static void hello(Collection x){
   System.out.println("Collection");
}

public static void hello(List x){
   System.out.println("List");
}

public static void main(String[] args){
   Collection col = new ArrayList();
   hello(col);
}

لا يستخدم وقت التشغيل نوع وهي قائمة ، فإنه يستخدم في تجميع الوقت النوع الذي هو جمع وبالتالي يطبع "جمع".

وأهيب بك أن تقرأ فعالة جافا, التي فتحت عيني على بعض الحالات الزاوية من JLS.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top