لماذا لا يمتد Java autoboxing إلى استدعاءات الطريقة لأنواع الأنواع التلقائية؟

StackOverflow https://stackoverflow.com/questions/4242

  •  08-06-2019
  •  | 
  •  

سؤال

أريد تحويل بدائية إلى سلسلة، وحاولت:

myInt.toString();

فشل هذا مع الخطأ:

int cannot be dereferenced

الآن، أفهم أن الأوليات ليست أنواعًا مرجعية (أي ليست كائنًا) وبالتالي لا يمكن أن تحتوي على طرق.ومع ذلك، قدمت Java 5 خاصية التشغيل التلقائي والفتح (على غرار C#...)الذي لم يعجبني أبدًا في C#، ولكن هذا خارج عن الموضوع).لذلك مع التشغيل التلقائي، أتوقع أن يقوم ما ورد أعلاه بتحويل myInt إلى عدد صحيح ثم استدعاء toString() على ذلك.

علاوة على ذلك، أعتقد أن لغة C# تسمح بمثل هذه المكالمة، إلا إذا كنت أتذكر بشكل غير صحيح.هل هذا مجرد عيب مؤسف في مواصفات التشغيل التلقائي/إلغاء التغليف في Java، أم أن هناك سببًا وجيهًا لذلك؟

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

المحلول

لا يصل نظام Java autoboxing/unboxing إلى الحد الذي يسمح لك بإلغاء الإشارة إلى عنصر بدائي، لذلك يمنعه برنامج التحويل البرمجي الخاص بك.المترجم الخاص بك لا يزال يعرف myInt باعتبارها بدائية.هناك ورقة حول هذه المسألة في jcp.org.

يعد Autoboxing مفيدًا بشكل أساسي أثناء التعيين أو تمرير المعلمة - مما يسمح لك بتمرير عنصر بدائي ككائن (أو العكس)، أو تعيين عنصر بدائي لكائن (أو العكس).

لذا لسوء الحظ، سيكون عليك القيام بذلك على النحو التالي:(مجد باتريك، لقد تحولت إلى طريقتك)

Integer.toString(myInt);

نصائح أخرى

كما سبق أن قال جاستن، ولكن يجب عليك القيام بذلك بدلاً من ذلك:

Integer.toString(myInt);

إنه يحفظ تخصيصًا أو اثنين ويكون أكثر قابلية للقراءة.

هناك طريقة أخرى للقيام بذلك وهي استخدام:

String.valueOf(myInt);

يتم تحميل هذه الطريقة بشكل زائد لكل نوع بدائي و Object.بهذه الطريقة لن تضطر حتى إلى التفكير في النوع الذي تستخدمه.سوف تستدعي تطبيقات هذه الطريقة الطريقة المناسبة من النوع المحدد لك، على سبيل المثال. Integer.toString(myInt).

يرى http://java.sun.com/javase/6/docs/api/Java/lang/String.html.

يبدو وكأنه عيب في المواصفات لي

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

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 أو لا تستخدمه على الإطلاق!

بناء الجملة الصحيح الأقرب إلى المثال الخاص بك هو

((Integer) myInt).toString();

عندما ينتهي المترجم، فهذا يعادل

Integer.valueOf(myInt).toString();

ومع ذلك، فإن هذا لا يعمل بشكل جيد مثل الاستخدام التقليدي، String.valueOf(myInt), ، لأنه، باستثناء حالات خاصة، يقوم بإنشاء مثيل عدد صحيح جديد، ثم يرميه بعيدًا على الفور، مما يؤدي إلى المزيد من البيانات غير الضرورية.(يتم تخزين مجموعة صغيرة من الأعداد الصحيحة مؤقتًا، ويمكن الوصول إليها عن طريق الوصول إلى المصفوفة.) ربما أراد مصممو اللغة تثبيط هذا الاستخدام لأسباب تتعلق بالأداء.

يحرر:سأكون ممتنًا إذا علق الناخب (الناخبون) حول سبب عدم فائدة ذلك.

في لغة C#، الأعداد الصحيحة ليست أنواعًا مرجعية ولا يجب وضعها في صندوق حتى تتمكن من ذلك إلى سلسلة() ليتم استدعاؤها.هم نكون ومع ذلك، تعتبر كائنات في إطار العمل (باعتبارها ValueType، لذا فهي تحتوي على دلالات قيمة).في CLR، يتم استدعاء الأساليب على الأوليات عن طريق تحميلها "بشكل غير مباشر" على المكدس (ldind).

كما أشار الجميع، يتيح لك نظام التشغيل التلقائي تبسيط بعض التعليمات البرمجية، ولكن لا يمكنك التظاهر بأن العناصر الأولية هي أنواع معقدة.

ومن المثير للاهتمام أيضًا: "Autoboxing هو اختراق على مستوى المترجم" في جافا.يعد Autoboxing في الأساس بمثابة خدعة غريبة تمت إضافتها إلى Java.الدفع هذا المشنور لمزيد من التفاصيل حول كم هو غريب.

سيكون من المفيد أن تحدد Java طرقًا ثابتة معينة للعمل على الأنواع البدائية ودمج بعض السكر النحوي في المترجم بحيث

5.asInteger

سيكون معادلاً ل

some.magic.stuff.Integer.asInteger(5);

لا أعتقد أن مثل هذه الميزة قد تتسبب في عدم التوافق مع أي تعليمات برمجية يتم تجميعها وفقًا للقواعد الحالية، كما أنها ستساعد في تقليل الفوضى النحوية في كثير من الحالات.إذا قامت Java بإلغاء الإشارة التلقائية للأوليات التي تم إلغاء مرجعيتها، فقد يفترض الناس أنها كانت تقوم بتعيين بناء جملة إلغاء المرجعية لاستدعاءات الطريقة الثابتة (وهو ما يحدث فعليًا في .NET)، وبالتالي فإن العمليات المكتوبة بهذا النموذج لم تكن أكثر تكلفة مما ستكون عليه استدعاءات الطريقة الثابتة المكافئة.إضافة ميزة لغة جديدة من شأنها أن تشجع الأشخاص على كتابة تعليمات برمجية سيئة (على سبيل المثال.لا تبدو البدائيات التي تم إلغاء الإشارة إليها في الملاكمة التلقائية) فكرة جيدة، على الرغم من أن السماح بأساليب نمط إلغاء الإشارة قد يكون كذلك.

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