JavaRush /مدونة جافا /Random-AR /صب (تحويل) الأنواع البدائية في جافا

صب (تحويل) الأنواع البدائية في جافا

نشرت في المجموعة
مرحبًا! أثناء تصفحك لـ JavaRush، صادفت أنواعًا بدائية أكثر من مرة. فيما يلي قائمة قصيرة بما نعرفه عنهم:
  1. إنها ليست كائنات وتمثل قيمة مخزنة في الذاكرة
  2. هناك عدة أنواع من الأنواع البدائية:
    • الأعداد الكلية - byte، short، int،long
    • أرقام الفاصلة العائمة (كسرية) - floatوdouble
    • منطقية -boolean
    • رمزي (للإشارة إلى الحروف والأرقام) -char
  3. كل واحد منهم لديه نطاق خاص به من القيم:
نوع بدائي الحجم في الذاكرة مدى من القيم
بايت 8 بت -128 إلى 127
قصير 16 بت إلى -32768 إلى 32767
شار 16 بت من 0 إلى 65536
كثافة العمليات 32 بت من -2147483648 إلى 2147483647
طويل 64 بت من -9223372036854775808 إلى 9223372036854775807
يطفو 32 بت من (2 إلى الأس -149) إلى ((2-2 إلى الأس -23)*2 إلى الأس 127)
مزدوج 64 بت من (-2 إلى الأس 63) إلى ((2 إلى الأس 63) - 1)
منطقية 8 (عند استخدامها في المصفوفات)، 32 (عند استخدامها في غير المصفوفات) صحيحة أو خاطئة
ولكن، بالإضافة إلى القيم، تختلف الأنواع أيضًا في حجم الذاكرة. intيأخذ أكثر من byte. أ- longأكثر من short. يمكن مقارنة مقدار الذاكرة التي تشغلها البدائيات بالدمى المتداخلة: التوسع والانكماش للأنواع البدائية - 2 توجد مساحة خالية داخل الدمية المتداخلة. كلما كانت دمية التعشيش أكبر، زادت المساحة. longيمكننا بسهولة وضع واحدة أصغر داخل دمية تعشيش كبيرة int. تناسبها بسهولة ولا تحتاج إلى القيام بأي شيء إضافي. في Java، عند العمل مع العناصر الأولية، يُسمى هذا بالتحويل التلقائي. وبطريقة أخرى يطلق عليه امتدادا. فيما يلي مثال تمديد بسيط:
public class Main {

   public static void main(String[] args) {

       int bigNumber = 10000000;

       byte littleNumber = 16;

       bigNumber = littleNumber;
       System.out.println(bigNumber);
   }
}
هنا نقوم بتعيين قيمة byteللمتغير int. كانت المهمة ناجحة وبدون أي مشاكل: القيمة المخزنة في byteتشغل مساحة ذاكرة أقل مما "تناسب" في int. "دمية التعشيش الصغيرة" (القيمة byte) تتناسب بسهولة مع "دمية الماتريوشكا الكبيرة" (المتغيرة int). إنها مسألة أخرى عندما تحاول القيام بالعكس - ضع قيمة كبيرة في متغير غير مصمم لمثل هذه الأحجام. من حيث المبدأ، لن تعمل هذه الحيلة مع دمى التعشيش الحقيقية، ولكنها ستعمل في جافا، ولكن مع الفروق الدقيقة. دعونا نحاول وضع قيمة intفي متغير short:
public static void main(String[] args) {

   int bigNumber = 10000000;

   short littleNumber = 1000;

   littleNumber = bigNumber;//error!
   System.out.println(bigNumber);
}
خطأ! يدرك المترجم أنك تحاول القيام بشيء غير قياسي، ويضع دمية ماتريوشكا كبيرة ( int) داخل دمية صغيرة ( short). خطأ الترجمة في هذه الحالة هو تحذير من المترجم: " مرحبًا، هل أنت متأكد من أنك تريد القيام بذلك؟ "إذا كنت متأكدًا، أخبر المترجم عن ذلك: " كل شيء على ما يرام، أعرف ما أفعله!" تسمى هذه العملية تحويل النوع الصريح أو التضييق . لإجراء تضييق، تحتاج إلى الإشارة بوضوح إلى النوع الذي تريد إلقاء القيمة عليه. بمعنى آخر، أجب عن سؤال المترجم: " حسنًا، أي من هذه الدمى الصغيرة تريد أن تضع هذه الدمية الكبيرة فيها؟" "في حالتنا سيبدو الأمر كما يلي:
public static void main(String[] args) {

   int bigNumber = 10000000;

   short littleNumber = 1000;

   littleNumber = (short) bigNumber;
   System.out.println(littleNumber);
}
لقد أشرنا بوضوح إلى أننا نريد دمج القيمة intفي متغير shortوتحمل المسؤولية عنها. يقوم المترجم، بعد أن يرى إشارة واضحة لنوع أضيق، بإجراء تحويل. ماذا ستكون النتيجة؟ إخراج وحدة التحكم: -27008 غير متوقع بعض الشيء. لماذا بالضبط مثل هذا؟ انها في الواقع بسيطة. كانت لدينا القيمة الأصلية - 10000000 وتم تخزينها في متغير intيستهلك 32 بت، وفي الشكل الثنائي بدا الأمر كما يلي: التوسع والانكماش للأنواع البدائية - 3 نكتب هذه القيمة للمتغير short، لكنه يمكنه تخزين 16 بت فقط! وبناء على ذلك، سيتم نقل أول 16 بت فقط من رقمنا إلى هناك، وسيتم التخلص من الباقي. ونتيجة لذلك، shortسيحتوي المتغير على القيمة التوسع والانكماش للأنواع البدائية - 4، والتي تساوي تمامًا -27008 في النموذج العشري، ولهذا السبب "طلب المترجم التأكيد" في شكل تحويل صريح إلى نوع معين. أولاً، يوضح أنك تتحمل مسؤولية النتيجة، وثانيًا، يخبر المترجم بمقدار المساحة التي يجب تخصيصها عند صب الأنواع. بعد كل شيء، إذا قمنا في المثال الأخير بالكتابة int، byteوليس إلى short، لكان لدينا 8 بتات فقط تحت تصرفنا، وليس 16، وكانت النتيجة ستكون مختلفة. بالنسبة للأنواع الكسرية ( floatو double)، يحدث التضييق بشكل مختلف. إذا حاولت تحويل هذا الرقم إلى نوع صحيح، فسيتم تجاهل الجزء الكسري الخاص به.
public static void main(String[] args) {

   double d = 2.7;

   long x = (int) d;
   System.out.println(x);
}
إخراج وحدة التحكم: 2

نوع البيانات شار

أنت تعلم بالفعل أن نوع char يُستخدم لعرض الأحرف الفردية.
public static void main(String[] args) {

   char c = '!';
   char z = 'z';
   char i = '8';

}
ولكن لديها عدد من الميزات التي من المهم أن نفهم. دعونا نلقي نظرة مرة أخرى على الجدول الذي يحتوي على نطاقات القيم:
نوع بدائي الحجم في الذاكرة مدى من القيم
بايت 8 بت -128 إلى 127
قصير 16 بت -32768 إلى 32767
شار 16 بت من 0 إلى 65536
كثافة العمليات 32 بت من -2147483648 إلى 2147483647
طويل 64 بت من -9223372036854775808 إلى 9223372036854775807
يطفو 32 بت من (2 إلى الأس -149) إلى ((2-2 إلى الأس -23)*2 إلى الأس 127)
مزدوج 64 بت من (-2 إلى الأس 63) إلى ((2 إلى الأس 63)-1)
منطقية 8 (عند استخدامها في المصفوفات)، 32 (عند استخدامها في غير المصفوفات) صحيحة أو خاطئة
النوع charله نطاق رقمي من 0 إلى 65536. ولكن ماذا يعني هذا؟ بعد كل شيء، charهذه ليست مجرد أرقام، ولكن أيضًا أحرف وعلامات ترقيم... والحقيقة هي أن القيم charيتم تخزينها في Java بتنسيق Unicode. لقد واجهنا Unicode بالفعل في إحدى المحاضرات السابقة. ربما تتذكر أن Unicode هو معيار لترميز الأحرف يتضمن أحرفًا من جميع اللغات المكتوبة في العالم تقريبًا. بمعنى آخر، هذه قائمة بالرموز الخاصة التي تحتوي على رمز لأي حرف تقريبًا من أي لغة. جدول Unicode العام كبير جدًا، وبالطبع لا يحتاج إلى حفظه عن ظهر قلب. هنا، على سبيل المثال، جزء منه: التوسع والانكماش للأنواع البدائية - 5 الشيء الرئيسي هو فهم مبدأ تخزين القيم char، وتذكر أنه بمعرفة رمز رمز معين، يمكنك دائمًا الحصول عليه في البرنامج. دعونا نجرب هذا مع بعض الأرقام العشوائية:
public static void main(String[] args) {

   int x = 32816;

   char c = (char) x ;
   System.out.println(c);
}
إخراج وحدة التحكم: هذا هو التنسيق الذي يتم تخزين الأحرف به في Java char. يتوافق كل حرف مع رقم - رمز رقمي مكون من 16 بت، أو بايتين. Unicode 32816 يتوافق مع الحرف 耰. انتبه لهذه اللحظة. في هذا المثال استخدمنا المتغير int. وتحتل 32 بت من الذاكرة , في حين char16 . اخترنا هنا لأن الرقم الذي نحتاجه، 32816، خارج النطاق . على الرغم من أن الحجم ، مثل القصير، هو 16 بت، إلا أنه لا توجد أرقام سالبة في النطاق، وبالتالي فإن النطاق "الإيجابي" أكبر بمرتين (65536 بدلاً من 32767 ). يمكننا استخدام طالما أن الكود الخاص بنا يقع ضمن نطاق 65536. ولكن إذا أنشأنا رقمًا ، فسوف يستغرق أكثر من 16 بت. وعند التضييق على الأنواع: intshortcharcharcharshortintint >65536
char c = (char) x;
سيتم التخلص من البتات الإضافية، وستكون النتيجة غير متوقعة تمامًا.

ميزات إضافة شار والأعداد الصحيحة

دعونا نلقي نظرة على هذا المثال غير العادي:
public class Main {

   public static void main(String[] args) {

      char c = '1';

      int i = 1;

       System.out.println(i+c);
   }
}
إخراج وحدة التحكم: 50 O_O أين المنطق؟ 1+1، من أين جاء الـ50؟! أنت تعلم بالفعل أن القيم charيتم تخزينها في الذاكرة كأرقام في النطاق من 0 إلى 65536، مما يمثل Unicode لشخصيتنا. التوسع والانكماش للأنواع البدائية - 6 حتى هنا هو عليه. عندما نقوم بإجراء عملية الجمع ويتم تحويل charبعض أنواع الأعداد الصحيحة charإلى الرقم الذي يتوافق معها في Unicode. عندما أضفنا 1 و'1' إلى الكود الخاص بنا، تم تحويل الرمز '1' إلى الكود الخاص به، وهو 49 (يمكنك التحقق من ذلك في الجدول أعلاه). ولذلك أصبحت النتيجة 50. لنأخذ مرة أخرى صديقنا القديم -كمثال ، ونحاول إضافته مع بعض الأرقام.
public static void main(String[] args) {

   char c = '耰';
   int x = 200;

   System.out.println(c + x);
}
إخراج وحدة التحكم: 33016 لقد اكتشفنا بالفعل أنه يتوافق مع الكود 32816. وعندما نضيف هذا الرقم و200، نحصل على النتيجة بالضبط - 33016 :) آلية التشغيل، كما ترون، بسيطة للغاية.
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION