نحوه راه اندازی گوشی های هوشمند و رایانه های شخصی. پرتال اطلاعاتی
  • خانه
  • سیستم عامل
  • ریختن یک رشته به یک عدد جاوا. تبدیل رشته های جاوا به مقادیری از انواع دیگر

ریختن یک رشته به یک عدد جاوا. تبدیل رشته های جاوا به مقادیری از انواع دیگر

این یک موضوع نسبتاً بزرگ است، اما ما سعی خواهیم کرد تا حد امکان به طور کامل و فشرده به آن بپردازیم. زمانی که به انواع ابتدایی جاوا نگاه کردیم، تا حدی به این موضوع پرداختیم.

جاوا امکان تبدیل بین مقادیر صحیح و ممیز شناور را فراهم می کند. همچنین می توانید مقادیر عدد صحیح و ممیز شناور را به مقادیر کاراکتر تبدیل کنید و بالعکس، زیرا هر کاراکتر مربوط به یک رقم یونیکد است. در واقع نوع بولی تنها نوع اولیه در جاوا است که نمی توان آن را به نوع اولیه دیگری تبدیل کرد. همچنین، هر نوع اولیه دیگری را نمی توان به بولی تبدیل کرد.

تبدیل نوع در جاوا دو نوع است: ضمنیو صریح.

تبدیل نوع ضمنیدر صورت وجود شرایط زیر اجرا می شود:

  1. هر دو نوع سازگار هستند
  2. طول نوع هدفبزرگتر یا مساوی طول نوع اصلی است

در تمام موارد دیگر، استفاده کنید تبدیل نوع صریح.

همچنین دو نوع تبدیل وجود دارد:

  1. تبدیل گسترده
  2. تبدیل باریک

تحول گسترده ( تبدیل گسترده) در صورتی رخ می دهد که یک مقدار از یک نوع به نوع گسترده تر، با محدوده بزرگتر تبدیل شود مقادیر مجاز. جاوا تبدیل‌های گسترده‌تری را به‌طور خودکار انجام می‌دهد، برای مثال، اگر یک مقدار واقعی از نوع int به متغیری از نوع double یا مقداری از نوع char به متغیری از نوع int اختصاص دهید. تبدیل ضمنی همیشه از نوع گسترش دهنده است.

اما ممکن است چند چنگک کوچک در اینجا وجود داشته باشد. به عنوان مثال، اگر یک مقدار int به یک مقدار float تبدیل شود. و مقدار int در نمایش باینری بیشتر از 23 است بیت های مهم، پس از دست دادن دقت ممکن است، زیرا نوع شناور دارای 23 بیت برای قسمت صحیح است. همه بیت های کممقادیر int که در مانتیس 23 بیتی یک شناور قرار نمی‌گیرند کنار گذاشته می‌شوند، بنابراین اگرچه ترتیب اعداد حفظ می‌شود، اما دقت از بین می‌رود. همین امر در مورد تحول نیز صادق است نوع بلنددوبل تایپ کنید

گسترش تبدیل نوع جاوا نیز می تواند به صورت زیر نمایش داده شود:

خطوط جامدتبدیل هایی را که بدون از دست دادن داده انجام می شود را نشان می دهد. خطوط چین نشان می دهد که ممکن است در حین تبدیل دقت از دست برود.

شایان ذکر است که چرا مثلاً نوع بایت به طور خودکار (به طور ضمنی) به نوع char تبدیل نمی شود، اگرچه عرض نوع بایت 8 بیت است و نوع کاراکتر 16 است، در مورد تبدیل نیز همینطور است. از نوع کوتاه به char. این به این دلیل است که بایت و شورت انواع داده های امضا شده هستند، در حالی که char بدون علامت هستند. بنابراین، در این موردشما باید از یک Cast صریح استفاده کنید، زیرا باید به صراحت به کامپایلر بگویید که می‌دانید چه می‌خواهید و چگونه بیت علامت بایت و انواع کوتاه هنگام تبدیل به char مدیریت می‌شود.

رفتار یک مقدار char در بیشتر موارد مشابه رفتار یک مقدار از نوع عدد صحیح است، بنابراین یک مقدار char را می توان در هر جایی که مقدار int یا long مورد نیاز است استفاده کرد. با این حال، به یاد بیاورید که نوع char بدون علامت است، بنابراین رفتار متفاوتی با نوع کوتاه دارد، حتی اگر محدوده هر دو نوع 16 بیت باشد.

کوتاه س = ( کوتاه ) 0xffff; // این بیت ها عدد -1 را نشان می دهند
کاراکتر ج = "\ffff"; // همان بیت ها یک کاراکتر یونیکد را نشان می دهند
بین المللی i1 = س; // تبدیل از short به int -1 را می دهد
بین المللی i2 = ج; // تبدیل char به int 65535 را به دست می دهد

تغییر شکل باریک ( تبدیل باریک) در صورتی رخ می دهد که مقدار به مقداری از نوع تبدیل شود که محدوده آن از مقدار اصلی گسترده تر نباشد. تبدیل های باریک همیشه ایمن نیستند: برای مثال، تبدیل مقدار صحیح 13 به بایت منطقی است، اما تبدیل 13000 به بایت غیر منطقی است زیرا بایت فقط می تواند اعداد بین 128- تا 127 را ذخیره کند. از آنجایی که داده ها می توانند در طول تبدیل باریک از بین بروند، کامپایلر جاوا به چنین تبدیلی مخالفت می کند، حتی اگر مقدار تبدیل شده در محدوده باریک تر از نوع مشخص شده باشد:

بین المللی من = 13 ;
بایت ب = من ; // کامپایلر این عبارت را حل نمی کند

تنها استثنای قاعده، اختصاص یک عدد صحیح واقعی (یک مقدار int) به یک بایت یا متغیر کوتاه در صورتی که لفظ با محدوده متغیر مطابقت داشته باشد.

یک تبدیل باریک همیشه یک تبدیل نوع صریح است..

تبدیل صریح انواع ابتدایی

عملگر تبدیل نوع صریح یا به طور خاص ریخته گری نوع است براکت های گرد، که در داخل آن نوع تبدیل به آن مشخص شده است - (نوع). مثلا:

بین المللی من = 13 ;
بایت ب = ( بایت ) من ; // تبدیل اجباری int به بایت
من = ( بین المللی ) 13.456 ; // تبدیل اجباری دوبل نوع literal به int 13

ریخته گری از نوع اولیه بیشتر مورد استفاده قرار می گیرد برای تبدیل مقادیر ممیز شناور به اعداد صحیح. که در آن قسمت کسریمقادیر ممیز شناور به سادگی کنار گذاشته می شوند(یعنی مقدار ممیز شناور به سمت صفر گرد می شود نه به سمت نزدیکترین عدد صحیح). اساسا فقط قسمت عدد صحیح را بگیرید نوع واقعی و از قبل به نوع عدد صحیح هدف ریخته شده است.

هنگام آوردن یک جادار تر نوع عدد صحیحبه یک کم ظرفیت تر، بیت های بالا به سادگی دور ریخته می شوند. این اساساً مانند مدول تقسیم مقدار ریخته‌گری بر محدوده نوع هدف (مثلاً 256 برای بایت) است.

خیلی بزرگه یک عدد کسریوقتی به یک عدد صحیح فرستاده می شود، MAX_VALUE یا MIN_VALUE می شود.

خیلی بزرگه دو برابروقتی به شناور Float.POSITIVE_INFINITY یا Float.NEGATIVE_INFINITY می شود.

جدول زیر یک شبکه است که در آن برای هر نوع اولیه، انواعی که می توان به آنها تبدیل کرد و روش تبدیل مشخص شده است. حرف ندر جدول به این معنی است که تبدیل امکان پذیر نیست. حرف Yبه معنای تبدیل گسترده ای است که به طور خودکار انجام می شود. حرف بابه معنای تبدیل باریکی است که به بازیگری واضح نیاز دارد. سرانجام، Y*به معنای تبدیل گسترده خودکار است که در طی آن مقدار ممکن است برخی از بیت های کم اهمیت را از دست بدهد. این می تواند هنگام تبدیل int یا long به float یا double اتفاق بیفتد. انواع ممیز شناور محدوده بزرگتری نسبت به انواع عدد صحیح دارند، بنابراین int یا long را می توان به صورت float یا double نشان داد. با این حال، انواع ممیز شناور اعداد تقریبی هستند و ممکن است همیشه به اندازه انواع عدد صحیح شامل ارقام مهم در مانتیس نباشند.

گسترش خودکار نوع در عبارات

همچنین لازم به ذکر است که یک بار دیگر به ارتقاء خودکار (بسط) انواع در عبارات اشاره می شود. ما قبلاً هنگامی که انواع داده‌های صحیح و عملیات روی آنها را در نظر می‌گرفتیم با آن مواجه شده‌ایم، اما هنوز هم ارزش یادآوری در اینجا را دارد تا حتی بهتر درک شود و علاوه بر این، مستقیماً با این موضوع مرتبط باشد. در مثال زیر علامت @ + , , * , / و غیره.

یعنی تمام لفظهای اعداد صحیح در عبارات و همچنین انواع بایت, کوتاهو کاراکترگسترش به بین المللی . اگر همانطور که در بالا توضیح داده شد، عبارت شامل موارد دیگر، بیشتر نباشد انواع بزرگداده ها ( طولانی, شناوریا دو برابر). بنابراین مثال بالا باعث خطای کامپایل می شود زیرا متغیر جنوع دارد بایتو عبارت b+1 در نتیجه ارتقای خودکار از نوع است بین المللی.

ریخته گری نوع ضمنی در عبارات انتساب ترکیبی

اگر چه این بخشو به تبدیل نوع ضمنی (ریخته گری) اشاره دارد، توضیح آن را در اینجا دادیم، زیرا در این مورد بسط نوع خودکار در عبارات نیز کار می کند و سپس بازیگران ضمنیانواع اینجا یک سپاه باله است. فکر می کنم مثال زیر آن را روشن می کند. همانطور که در توضیح قبلی علامت @ برای مثال به معنای هر عملگر معتبر است + , , * , / و غیره.

این را باید با یک مثال ساده توضیح داد:

بایت b2 = 50 ;
b2 = b2 * 2 ; // کامپایل نمی شود
b2 *= 2 ; //کامپایل، اگرچه معادل b2 = b2 * 2 است

خط دوم در مثال به دلیل بسط نوع خودکار در عبارات کامپایل نمی شود، زیرا عبارت b2*2 دارای نوع int است، زیرا بسط نوع خودکار رخ می دهد (الفظ اعداد صحیح در عبارات همیشه int هستند). خط سوم به راحتی کامپایل می شود، زیرا نوع ریخته گری ضمنی در عبارت انتساب ترکیبی در آن کار می کند.

Boxing/unboxing - تبدیل انواع بدوی به اشیاء بسته بندی

بوکس و جعبه گشایی نیز موضوع بسیار بزرگی است، اما بسیار ساده است.

اساسا boxing و unboxing تبدیل انواع اولیه به اشیاء لفافی و بالعکس است.

برای اشیاء بسته بندی از انواع ابتدایی، همه آنچه در بالا گفته شد صدق می کند.

هنگام تجزیه هر یک از انواع ابتدایی، کلاس های Wrapper در جداول ذکر شده است. اما پس از آن فقط ذکر در جدول بود.

بنابراین، برای هر نوع اولیه برادر بزرگتر آن وجود دارد و اصلاً ابتدایی نیست، بلکه یک کلاس واقعی است، با فیلدها و متدها. و برای هر جفت چنین، تبدیل خودکار امکان پذیر است.

معمولاً اگر برنامه تعداد زیادی داشته باشد محاسبات ریاضی، بهتر است از انواع اولیه استفاده شود، زیرا از نظر منابع سریعتر و مقرون به صرفه تر است، اما گاهی اوقات نیاز به تبدیل یک نوع اولیه به یک شی وجود دارد.

من یک مثال ساده می زنم:

بین المللی i3 ;
بایت b2 = 3 ;
بایت ها myB ;
myB= b2;
myB++;
b2= myB;
i3= myB;

اگر هنوز مشخص نیست که چرا این مورد نیاز است، پس ترسناک نیست، فقط یک گره را به عنوان یادگاری گره بزنید.

AT این درسما به شما در مورد کمی سردرد برای برنامه نویسان خواهیم گفت - نوع ریخته گری. ریخته گری نوع چیست؟ این هر نوع تبدیل داده است.
مثلا:

int b = 3;
double a = 1.0 * b;//تبدیل نوع
a = (دو) b;//تبدیل نوع

بنابراین، می توانید دو روش برای تغییر نوع مشاهده کنید:

  • انجام برخی عملیات بر روی یک شی
  • تبدیل صریح

چه انواعی را می توان ریخت؟ می توانید به انواع داده هایی که در یک سلسله مراتب هستند ارسال کنید. فرض کنید می توانید یک عدد صحیح را به یک عدد واقعی تبدیل کنید و بالعکس. می توانید کلاس Student را به کلاس User و غیره ارسال کنید. بدیهی است که انداختن رشته به یک عدد بی فایده است، زیرا این اشیاء متفاوت هستند. در این حالت معمولاً از عملیات ویژه استفاده می شود.
کم و بیش، تقریبا کاربران با تجربهممکن است سوال زیر مطرح شود:

int b = 3;
double a = b;//تبدیل نوع 1
b = (int) a؛ // نوع تبدیل 2

چرا می توان به نوع داده دوگانه، نوع داده int را اختصاص داد و کامپایلر خطایی ایجاد نمی کند، اما برای فرستادن double به int، باید به صراحت نوع آن را مشخص کنید؟ به نظر می رسد که تبدیل های ایمن، به عنوان مثال از int به دو برابر یا از پسر به والد، گسترش نامیده می شود، یعنی ما به یک نوع داده با قابلیت های کمتر برای گسترش می دهیم، به عنوان مثال، به یک نوع داده عدد صحیح، فرصت تبدیل شدن را می دهیم. واقعی، دامنه آن را گسترش می دهد. اگر نوع داده‌ای که می‌خواهیم برای آن ارسال کنیم، شامل نوع داده‌ای باشد که می‌خواهیم برای انواع پایه ارسال کنیم، تبدیل در حال گسترش است.
تبدیل های باریک همیشه با مقداری از دست دادن اطلاعات همراه است، به عنوان مثال، هنگام تبدیل از double به int، همه مقادیر را پس از نقطه اعشار از دست می دهیم، که باعث نگرانی رایانه می شود و فقط نشانه صریحنوع داده می تواند به او اطمینان دهد که ما این تبدیل را با حسن نیت و با حافظه محکم انجام می دهیم.
دوباره مثالی را با اشکال در نظر بگیرید:

کلاس عمومی شکل(
}
کلاس عمومی مربع گسترش شکل (
}
مربع مربع؛
شکل شکل = مربع؛//تحولات گسترده
مربع = شکل؛//تحولات باریک

به نظر می رسد تبدیل شدن از پسر به پدر و مادر، برعکس، ما در حال تنگ شدن هستیم، و گسترش نمی دهیم، دلیل چیست؟ و دلیل آن این است که در واقع کلاس Square حاوی تمام اطلاعات کلاس Shape است و با تبدیل پسر به پدر فقط اطلاعات مربوط به پسر را از دست می دهیم که در این لحظهممکن است مهم نباشد، اما با تبدیل از Shape به Square می‌توانیم به چنین وضعیتی دست پیدا کنیم که به سادگی داده‌های لازم برای کار کلاس را نداشته باشیم، مثلاً اگر در مورد آن صحبت کنیم، اندازه مربع را نداریم. مثال بالا
و در پایان درس، عملگر instanceof را در نظر بگیرید، اگر شی دارای یک نوع معین باشد، مقدار true را برمی گرداند:

If(new Square() instanceof Shape)(//false

جاوا یک زبان برنامه نویسی قوی تایپ شده است، به این معنی که هر عبارت و هر متغیر دارای یک تایپ قوی است نوع خاصیدر حال حاضر در زمان تدوین
انواع گچ
جاوا هفت نوع بازیگر ارائه می دهد:

  • هویت؛

  • گسترش یک نوع اولیه (بسط بدوی)؛

  • نوع بدوی باریک (narrowing primitive);

  • پسوند نوع شی (مرجع گسترده)؛

  • باریک شدن نوع شی (مرجع باریک شدن)؛

  • تبدیل به رشته (رشته)؛

  • تبدیل ممنوع (ممنوع);
بیایید آنها را جداگانه در نظر بگیریم.
دگرگونی هویت
ساده ترین آن تغییر هویت است. در جاوا، تبدیل یک عبارت از هر نوع دقیقاً به همان نوع همیشه قانونی است و موفقیت آمیز است.
این مهم است تا بتوانیم از لحاظ نظری استدلال کنیم که هر نوع در جاوا می تواند در یک تبدیل شرکت کند، حتی اگر یکسان باشد.
تبدیل نوع اولیه (بسط و باریک شدن)
برای انواع سادهانبساط به این معنی است که انتقال از نوع کم ظرفیت تر به ظرفیت بیشتر انجام می شود. به عنوان مثال، از نوع بایت (طول 1 بایت) به تایپ int (طول 4 بایت). این گونه دگرگونی ها به این معنا امن هستند نوع جدیدهمیشه تضمین می شود که حاوی تمام داده هایی است که در نوع قدیمی ذخیره شده است و بنابراین هیچ گونه از دست دادن داده رخ نمی دهد. به همین دلیل است که کامپایلر خود آن را به طور نامحسوس برای توسعه دهنده پیاده سازی می کند:

بایت=3;
int a=b;

19 تبدیل زیر در حال گسترش هستند:

  • از بایت به کوتاه، int، طولانی، شناور، دو برابر

  • از کوتاه به int، بلند، شناور، دوبل

  • از char به int، long، float، double

  • از int تا long، float، double

  • از طولانی به شناور، دو برابر

  • شناور به دو برابر شدن
توجه داشته باشید که نمی توانید از انواع کمتر از یا به char تبدیل کنید طول مساوی(بایت، کوتاه) یا برعکس به کوتاه از char بدون از دست دادن اطلاعات. این به دلیل این واقعیت است که char، بر خلاف سایر انواع عدد صحیح، امضا شده است.
با این حال، باید به خاطر داشت که حتی با گسترش، داده ها همچنان می توانند تحریف شوند. این در حال ریختن مقادیر int به نوع شناورو مقادیر ریخته گری از نوع long تا type float یا double. اگر چه این انواع کسری می توانند چیزهای زیادی را در خود جای دهند اعداد بزرگنسبت به اعداد صحیح مربوطه، اما ارقام مهم کمتری دارند.
مثلا:

طولانی a = 111111111111L;
شناور f=a;
a=(طولانی)f; // () فقط یک عملیات تبدیل نوع است
System.out.println(a); //نتیجه 111111110656

توجه داشته باشید - باریک شدن - به این معنی است که انتقال از نوع جادارتر به نوع کم ظرفیت تر انجام می شود. با چنین تبدیلی، خطر از دست دادن اطلاعات وجود دارد. به عنوان مثال، اگر یک int بزرگتر از 127 بود، وقتی به بایت فرستاده می شود، مقادیر بیت بزرگتر از هشتم از بین می رود. در جاوا، چنین تبدیلی باید به صراحت انجام شود، یعنی. برنامه نویس در کد باید به صراحت نشان دهد که قصد دارد چنین تبدیلی را انجام دهد و آماده از دست دادن داده است.
23 تبدیل زیر در حال باریک شدن هستند:

  • از بایت به کاراکتر

  • از کوتاه تا بایت، کاراکتر

  • از کاراکتر به بایت، کوتاه

  • از int به بایت، کوتاه، کاراکتر

  • از طولانی به بایت، کوتاه، char، int

  • از شناور به بایت، کوتاه، char، int، طولانی

  • از دو به بایت، کوتاه، char، int، طولانی، شناور
هنگام باریک کردن یک نوع عدد صحیح به یک نوع عدد صحیح باریک تر، تمام بیت های مرتبه بالا که در نوع جدید مناسب نیستند به سادگی کنار گذاشته می شوند. هیچ گرد کردن یا سایر اقداماتی برای به دست آوردن نتیجه صحیح تر انجام نمی شود:

System.out.println((byte)383);
System.out.println((byte)384);
System.out.println((بایت)-384);

نتیجه این خواهد بود:

127
-128
-128
مشاهده می شود که بیت علامت در حین باریک شدن تأثیری نداشته است ، زیرا به سادگی کنار گذاشته شد - نتیجه ریخته گری اعداد متقابل (384 ، -384) یکسان بود. در نتیجه، نه تنها قدر مطلق دقیق را می توان از دست داد، بلکه علامت کمیت را نیز می توان از دست داد.
این برای char نیز صادق است:

کاراکتر c=4000;
System.out.println((کوتاه)c);

نتیجه:

-25536
تبدیل نوع مرجع (بسط و باریک کردن)
تبدیل نوع شی به بهترین شکل با استفاده از درخت ارثی نشان داده می شود. یک مثال کوچک از وراثت را در نظر بگیرید:

classParent(
intx;
}

کلاس ChildY گسترش پدر و مادر(
int y;
}

کلاس ChildZ گسترش پدر و مادر(
intz;
}

هر کلاس یک فیلد با یک نام منحصر به فرد اعلام می کند. ما این فیلد را به عنوان نمونه ای از مجموعه ای از ویژگی های منحصر به فرد ذاتی در برخی از انواع شی در نظر خواهیم گرفت.
اشیاء کلاس Parent فقط یک فیلد x دارند، به این معنی که فقط مراجع از نوع Parent می توانند به چنین اشیایی ارجاع دهند. اشیاء کلاس ChildY دارای یک فیلد y و یک فیلد x است که از کلاس Parent به ارث رسیده است. بنابراین، ارجاعاتی از نوع ChildY یا Parent می توانند به چنین اشیایی اشاره کنند. مثال:

p والد = newChildY();

توجه داشته باشید که این مرجع p فقط می تواند به فیلد x شی ایجاد شده دسترسی داشته باشد. فیلد y در دسترس نیست زیرا کامپایلر، هنگام بررسی صحت عبارت p.y، نمی تواند پیش بینی کند که p مرجع به یک شی از نوع ChildY در زمان اجرا اشاره می کند. فقط نوع خود متغیر را تحلیل می کند و به عنوان Parent اعلام می شود، اما این کلاس فیلد y ندارد که باعث خطای کامپایل می شود.
به طور مشابه، اشیاء کلاس ChildZ دارای یک فیلد z و یک فیلد x هستند که از کلاس Parent به ارث رسیده است. این بدان معنی است که مراجعی مانند ChildZ و Parent می توانند به چنین اشیایی اشاره کنند.
بنابراین، ارجاعات از نوع Parent می توانند به یک شی از هر یک از سه نوع در نظر گرفته شده اشاره کنند، در حالی که مراجع از نوع ChildY و ChildZ فقط می توانند به اشیاء دقیقاً همان نوع اشاره کنند. اکنون می توانیم به تبدیل انواع مرجع بر اساس چنین درخت ارثی برویم.
Extension به معنای رفتن از یک نوع خاص تر به یک نوع کمتر خاص است، i.e. انتقال از فرزندان به والدین مشابه با انواع اولیه، این انتقال در مواقع لزوم توسط خود JVM انجام می‌شود و برای توسعه‌دهنده «نامرئی» است، یعنی نیازی به تبدیل خاصی ندارد.

والد p1=newChildY();
والد p2=newChildZ();

در هر دو خط متغیرها را تایپ کنیدمقداری از نوع متفاوت به والد اختصاص داده می شود، به این معنی که یک تبدیل رخ می دهد. چون افزونه است، به صورت خودکار انجام می شود و همیشه موفق می شود.
باید توجه داشت که با چنین تبدیلی هیچ اتفاقی برای خود شیء نمی افتد. علیرغم اینکه، برای مثال، فیلد y کلاس ChildY دیگر در دسترس نیست، این بدان معنا نیست که ناپدید شده است. چنین تغییر قابل توجهی در جسم امکان پذیر نیست. این از کلاس ChildY مشتق شده است و تمام ویژگی های خود را حفظ می کند. فقط نوع پیوندی که از طریق آن به شیء دسترسی پیدا می شود تغییر کرده است.
انتقال معکوس، یعنی حرکت به سمت پایین درخت ارث به سمت وراث، یک باریک شدن است. به عنوان مثال، در این مورد، انتقال از یک مرجع از نوع Parent، که می تواند به اشیاء سه کلاس اشاره کند، به مرجعی از نوع ChildY، که فقط می تواند به یکی از سه کلاس اشاره کند، بدیهی است که یک باریک شدن است. چنین انتقالی ممکن است امکان پذیر نباشد. اگر یک مرجع از نوع Parent به یک شی از نوع Parent یا ChildZ اشاره کند، در این صورت انتقال به ChildY غیرممکن است، زیرا در هر دو مورد شیء دارای فیلد y نیست که در کلاس ChildY اعلام شده است. بنابراین، هنگام محدود کردن، توسعه‌دهنده باید به صراحت نشان دهد که تلاش برای انجام چنین تحولی ضروری است. JVM صحت انتقال را در زمان اجرا بررسی می کند. در صورت امکان، تبدیل انجام می شود. اگر نه، خطایی رخ می دهد (معمولاً ClassCastException).

والد p=newChildY();
ChildYcy = (ChildY)p; //درست
والد p2=newChildZ();
ChildYcy2 = (ChildY)p2; //اشتباه

برای بررسی اینکه آیا انتقال مورد نظر امکان پذیر است، می توانید از عملگر instanceof استفاده کنید:

والد p=newChildY();
if (p instanceofChildY)(
ChildYcy = (ChildY)p;
}

والد p2=newChildZ();
if (p2 instance of ChildY) (
ChildYcy = (ChildY)p2;
}

والد p3=جدید والد();
if (p3 instanceofChildY)(
ChildYcy = (ChildY)p3;
}

AT این مثالهیچ خطایی رخ نخواهد داد اولین تحول ممکن است و انجام خواهد شد. در حالت دوم و سوم، شرایط دستور if کار نمی کند و بنابراین، انتقال نادرستی وجود نخواهد داشت.
تبدیل به رشته
هر نوع را می توان به یک رشته ریخت، یعنی. به عنوان مثال رشته رشته. چنین تبدیلی به دلیل این واقعیت استثنایی است که کاملاً همه انواع را پوشش می دهد.
انواع مختلف به صورت زیر به رشته تبدیل می شوند:

  • انواع عددی در نوشته شده است فرم متنبدون از دست دادن دقت نمایش ابتدا بر اساس مقدار اولیه، نمونه ای از کلاس “wrapper” مربوطه تولید می شود، سپس متد toString() روی آن فراخوانی می شود. اما از آنجایی که این اقدامات از بیرون نامرئی هستند، JVM آنها را بهینه می کند و مقادیر اولیه را مستقیماً به متن تبدیل می کند.

  • مقادیر بولی بسته به مقدار به رشته "true" یا "false" ریخته می شوند.

  • برای مقادیر شیء، متد toString() فراخوانی می شود. اگر متد null را برگرداند، نتیجه رشته "null" خواهد بود.

  • برای یک مقدار null، رشته "null" تولید می شود.
تبدیل های ممنوعه
همه انتقال‌ها بین انواع دلخواه مجاز نیستند. به عنوان مثال، تبدیل های ممنوعه عبارتند از: انتقال از هر نوع مرجع به ابتدایی و بالعکس (به جز تبدیل به یک رشته)، بولین را فقط می توان به این نوع یا به یک رشته تبدیل کرد. علاوه بر این، نمی توان طبقات واقع در شاخه های همسایه درخت ارث را به یکدیگر آورد. در مثالی که برای نشان دادن انواع مرجع در نظر گرفته شد، انتقال از ChildY به ChildZ ممنوع است.
این لیست از تغییرات ممنوعه تمام نشده است. این کاملاً گسترده است و در عین حال همه گزینه ها کاملاً واضح هستند ، بنابراین با جزئیات در نظر گرفته نمی شوند. کسانی که تمایل دارند می توانند دریافت کنند اطلاعات کاملاز مشخصات
البته تلاش برای انجام تبدیل ممنوعه باعث خطا می شود.

استفاده از گچ
موقعیت های تبدیل نوع را می توان به صورت زیر گروه بندی کرد:

  • تخصیص مقادیر به متغیرها (تخصیص). همه انتقال‌ها تحت چنین تحولی مجاز نیستند - محدودیت‌ها به گونه‌ای انتخاب می‌شوند که استثنایی رخ ندهد.

  • فراخوانی روش. این تبدیل برای آرگومان های متد یا سازنده فراخوانی شده اعمال می شود. چنین بازیگری هرگز خطا ایجاد نمی کند. ریخته گری نیز هنگام برگرداندن مقدار روش انجام می شود.

  • بازیگران صریح در این حالت به صراحت مشخص می شود که می خواهید مقدار اصلی را به کدام نوع ارسال کنید.

  • عملگر الحاق به رشته ای از آرگومان های خود تبدیل می کند.

  • بسط عددی عملیات عددیممکن است نیاز به تغییر در نوع آرگومان(های) داشته باشد. این تبدیل یک نام خاص دارد - توسعه یافته، زیرا انتخاب نوع هدف نه تنها به مقدار اولیه، بلکه به آرگومان دوم عملیات نیز بستگی دارد.
وظیفه شماره 8
استفاده از بازیگران برای سلسله مراتب کلاس خود را به پروژه اضافه کنید.

سخنران قبلی توضیح داده است تبدیل پایین، اما صعودی (به نظر من) نیاز به توضیح اضافی دارد، زیرا سوال بسیار محبوب و جالب است.

چگونه ریخته گری نوع صریح کار می کند

مثال شما تبدیل به بالا را نشان می دهد ( به روز رسانی):

فهرست coll = new ArrayList();

به روسی به صورت زیر ترجمه شده است: یک کلاغ مانند یک پرنده ایجاد کنید. یک آرایه پویا ایجاد کنید، صفحه را تایپ کنید. در اکثر مواقع، به روز رسانی کاملا غیر ضروری است.
با این حال، زمانی که سوالات ارثی به شما داده می‌شود، در مصاحبه‌های شغلی تایپ کستینگ کار می‌کند. به عنوان مثال، سایت quizful.net به طور کلی حاوی سوالات زیادی در مورد ریخته گری نوع است. بنابراین، من ویژگی هایی را که می دانم توضیح خواهم داد.

بنابراین، در مثال بالا، یک شی از نوع ArrayList و یک مرجع از نوع List ایجاد کرده ایم. بدیهیات این روش را به خاطر بسپارید:

1. می توانید به هر والدینی پیوند دهید. حتی خیلی قدیمی. یعنی می توانید مرجع coll را حتی به نوع Object ارسال کنید. کامپایلر از هر مرجع کلاس والد، یا والد-والد، یا والد-والد...والد صرفنظر می کند.

2. دسترسی به فیلد - همیشه فیلد مرجع را برمی گرداند، نه فیلد شی. اگر چنین فیلدی در کلاس مرجع وجود نداشته باشد، خطای کامپایل وجود خواهد داشت.

کلاس A (int x = 2; // فیلد والد) کلاس B A را گسترش می دهد (int x = 3؛ // فیلدی که باید با int والد y = 5 همپوشانی داشته باشد؛ // فیلدی که در کلاس والد نیست. ) آزمون کلاس ( اصلی خالی ثابت عمومی (رشته آرگ) ( A ab = new B(); //Up-conversion System.out.println("Int x = " + ab.x); ) )

برگشت Int x = 2 . اگر سعی می کنید به فیلد یک شی دسترسی پیدا کنید:

System.out.println("Int y = " + ab.y); //خطای کامپایل

کامپایلر شما خواهد گفت که اشتباه می کنید، زیرا چنین فیلدی را با مرجع (A ab) نمی بیند. همه موارد بالا همچنان اعمال می شود حتی اگر فیلدهای شما با اصلاح کننده های ثابت علامت گذاری شده باشند.

3. فراخوانی یک متد غیر استاتیک: در این صورت، متد شی را برمی گرداند. اما هنگام دسترسی به یک متد استاتیک، متد پیوند را برمی گرداند.

کلاس D( public void doSome()( //روش غیراستاتیک System.out.println("Nonstatic doSome from D"); ) public static void Action()( //Static متد System.out.println("عمل ثابت از D "); ) ) کلاس عمومی Okey گسترش D( public void doSome()( System.out.println("doSome from Okey"); ) public static void Action()( System.out.println("Static Action from Okey" );

doSome غیراستاتیک از Okey

استاتیک اکشن از D

پاسخ ساده است، یک متد غیر استاتیک یک متد شی است، یک متد استاتیک یک متد کلاسی است. وقتی یک متد غیراستاتیک را فرا می‌خوانیم، کامپایلر این را می‌فهمد: مثل یک کلاغ پرواز کن. هنگامی که ما ساکن را صدا می کنیم - به معنای واقعی کلمه، مانند یک پرنده پرواز کنید.

4. اگر فراخوانی متدی وجود داشته باشد که در کلاس شی توصیف شده است، اما در کلاس مرجع توصیف نشده است، یک خطای کامپایل رخ می دهد. زیرا متد با مرجع فراخوانی می شود:

کلاس A () کلاس B A را گسترش می دهد ( void someMethod()(); void public static main(string args) (A ab = new B(); ab.someMethod(); //خطای کامپایل. ) )

5. یک سازنده شی (هنگامی که با دستور جدید ایجاد می شود) به همان روشی کار می کند که اگر به کلاس خود ارجاع دهید.

مقاله ارائه شده:

  • نوشته شده توسط تیم امیدواریم برای شما مفید واقع شود. خواندن مبارک!
  • این یکی از مقالات ما است

تبدیل نوع موضوعی است که ممکن است برای برنامه نویسان مبتدی جاوا دلهره آور به نظر برسد. با این حال، ما به شما اطمینان می دهیم، در واقع، همه چیز ساده است. نکته اصلی برای درک بر اساس چه قوانینی تعامل بین متغیرها رخ می دهد و این را هنگام نوشتن برنامه به خاطر بسپارید. بنابراین، بیایید آن را بفهمیم.

در جاوا، 2 نوع تبدیل وجود دارد - یک تصویر برای کمک به شما:

به یاد بیاورید که کل "جهان جاوا" شامل موارد زیر است:

  • انواع ابتدایی (بایت، کوتاه، int، طولانی، کاراکتر، شناور، دوبل، بولی)
  • اشیاء

در این مقاله ما:

  • تبدیل نوع را برای انواع متغیرهای اولیه در نظر بگیرید
  • تبدیل اشیاء (رشته، اسکنر و غیره) در این مقاله در نظر گرفته نشده است، زیرا یک "جادو" جداگانه با اشیا اتفاق می افتد - این موضوع برای یک مقاله جداگانه است.
تبدیل خودکار

خوب، خوب، بیایید سعی کنیم بفهمیم "تبدیل خودکار" چیست.

به یاد داشته باشید که وقتی به انواع متغیرها نگاه کردیم (در مقاله) این را گفتیم یک متغیر نوعی "کانتینر" است A که می تواند مقداری را برای استفاده بعدی در برنامه ذخیره کند. ما همچنین در مورد این واقعیت صحبت کردیم که هر نوع متغیر دارای محدوده مقادیر معتبر و مقدار حافظه ای است که اشغال می کند. این علامتی است که در آن نوشته شده بود:

بنابراین این چیزی است که ما در واقع به آن می رسیم. علاوه بر این، برای شما به هیچ وجه آسان نبود که به شما محدوده هایی از مقادیر معتبر و مقدار حافظه اشغال شده داده شود.

بیایید برای مثال مقایسه کنیم:

1. بایت و کوتاه.بایت دارای محدوده کمتری از مقادیر معتبر نسبت به short است. یعنی بایت مانند یک جعبه کوچکتر است و short یک جعبه بزرگتر است. و این یعنی به طور خلاصه می توانیم بایت را تودرتو کنیم.

2. بایت و بین المللی. بایت دامنه مقادیر معتبر کمتری نسبت به int دارد. یعنی بایت مانند یک جعبه کوچکتر است و int یک جعبه بزرگتر است. و این یعنی ما می توانیم بایت را در int قرار دهیم.

3.int و long. int دارای محدوده کمتری از مقادیر معتبر نسبت به long است. یعنی int مانند یک جعبه کوچکتر است و long یک جعبه بزرگتر است. و این یعنی ما می توانیم در مدت طولانی لانه بیندازیم.

این یک نمونه از تبدیل خودکار است. این را می توان به صورت شماتیک در قالب تصویر زیر نشان داد:

بیایید ببینیم که این در عمل چگونه کار می کند.

مثال شماره 1

کد شماره 1 - اگر این کد را روی رایانه خود اجرا کنید،

کلاس تست ( بایت استاتیک اصلی (بایت a = 15؛ بایت b = a؛ System.out.println(b)؛ )

آزمون کلاس(

بایت a = 15 ;

بایت b = a ;

کد شماره 2 - اگر این کد را روی رایانه خود اجرا کنید، کنسول عدد 15 را نمایش می دهد

کلاس تست (اصطلاح خالی استاتیک عمومی (رشته آرگ) (بایت a = 15؛ int b = a؛ System.out.println(b)؛ )

آزمون کلاس(

اصلی خالی استاتیک عمومی (رشته آرگ)(

بایت a = 15 ;

int b = a ;

سیستم. بیرون . println(b)؛

و-و-و؟ آیا فکر می کنید که دفعاتی که همان شماره روی کنسول چاپ شد، و کد #1 فقط در نوع متغیر b با کد #2 متفاوت است پس فرقی بین آنها نیست؟ Eکه اینطور نیست

کد شماره 2 شامل خودکارتبدیل نوع ، اما در کد شماره 1 - no:

اگر چه عدد در اصل یکسان است، اما اکنون در b است در بارهیک ظرف بزرگتر که فضای دیسک بیشتری را اشغال می کند. با انجام این کار، JVM اجرا می کند تبدیل های خودکاربرای شما. او این را می داند بین المللیبیشتر از بایت .

قالب

نکته دیگر این است که اگر می خواهید چیزی را از یک ظرف بزرگتر به ظرف کوچکتر منتقل کنید.

ممکن است بدانید که یک ظرف بزرگتر حاوی چیزی است که در ظرف کوچک قرار می گیرد - اما JVM این را نمی داند و سعی می کند از شما در برابر خطا محافظت کند.

بنابراین، شما باید مستقیماً بگویید که وضعیت تحت کنترل است:

کلاس آزمون (اصلی خلأ استاتیک عمومی (آرگس های رشته ای) (int a=0؛ long b=15؛ a = (int) b؛ ))

آزمون کلاس(

اصلی خالی استاتیک عمومی (رشته آرگ)(

int a = 0 ;

طولانی b = 15 ;

a = (int ) b ;

در اینجا ما اضافه کرده ایم (int)قبل از ب. اگر متغیر آبود برای مثال بایت، در پرانتز خواهد بود (بایت) . فرمول کلیبه نظر می رسد که:

او می‌گوید: «ارزش (بزرگ‌تر) ایجاد کنید بیک متغیر از نوع (هدف) مورد نیاز من است بین المللی ".

اگر مشکلی پیش آمد.

تا کنون، با فرض اینکه می دانیم دقیقاً چه کاری انجام می دهیم، موقعیت ها را بررسی کرده ایم. اما اگر بخواهید چیزی را در ظرفی قرار دهید که در آن جا نمی شود چه؟

معلوم می شود که فقط آنچه "مناسب" در ظرف باقی می ماند. به عنوان مثال، بخش کسری اعداد ممیز شناور "قطع" خواهد شد:

//example 1 class Test ( Public void main(String args) ( double a=11.2345; int b=(int)a; System.out.println(b); // کنسول عدد 11 را نمایش می دهد) )

//مثال 1

آزمون کلاس(

اصلی خالی استاتیک عمومی (رشته آرگ)(

دو برابر a = 11.2345 ;

int b = (int ) a ;

سیستم. بیرون . println(b)؛ // کنسول عدد 11 را نمایش می دهد

باید به خاطر داشت که بخش کسری گرد نیست، آ دور انداخته شد.

اما اگر بخواهیم عددی خارج از محدوده قرار دهیم چه اتفاقی می افتد؟ به عنوان مثال، اگر در بایت (محدوده بایت از 128- تا 127) عدد 128 را قرار دهید؟ فکر می کنی 1 بگیریم؟ خیر ما -128 را دریافت می کنیم:

class Test ( public void main(string args) ( double a=128; byte b=(byte)a; System.out.println(b); //ما -128 را در کنسول خواهیم دید))

مقدار یک متغیر را می توان از روی چنین تبدیلی محاسبه کرد، اما هدف برنامه نویس جلوگیری از وضعیتی است که مقدار آن خارج از محدوده است، زیرا این می تواند منجر به کار اشتباهبرنامه ها.

وظایف:
  1. به صورت متوالی در کامپایلر تبدیل همه انواع اولیه به یکدیگر، از جمله انواع char را بنویسید و جدولی مانند این بسازید:
بایت کوتاه کاراکتر بین المللی طولانی شناور دو برابر بولی
بایت
کوتاه
کاراکتر
بین المللی
طولانی
شناور
دو برابر
بولی

در تقاطع، بنویسید: a - اگر تبدیل به طور خودکار انجام شود، روی - اگر نیاز به استفاده از تبدیل صریح دارید، x - اگر تبدیل امکان پذیر نیست.

* ریختن یک نوع به خود نامیده می شود همسان- نوشتن لازم نیست

  1. دوباره به اندازه هر نوع اولیه نگاه کنید. سعی کنید یک بلوک دیاگرام بسازید که نشان دهد کدام نوع ها کجا می روند. فلش‌های با برچسب «تبدیل گسترش» و «تحول باریک» را بکشید.
سوالات

هنگام مصاحبه برای یک موقعیت توسعه‌دهنده جاوا، ممکن است از شما خواسته شود:

در مورد تبدیل انواع داده های اولیه چه می دانید، آیا از دست دادن داده وجود دارد، آیا امکان تبدیل نوع بولین وجود دارد؟

سعی کنید به سوال پاسخ دهید.

به طور خلاصه:
  • اگر محتویات یک ظرف کوچکتر را در یک ظرف بزرگتر "قرار دهید"، تبدیل به صورت خودکار انجام می شود و نباید خطایی رخ دهد.
  • اگر نیاز به قرار دادن "مقدار از یک ظرف بزرگتر به ظرف کوچکتر" وجود دارد، باید مراقب باشید و از ریخته گری نوع صریح استفاده کنید.
  • هنگام ریخته گری شناور یا دو تا انتگرال، قسمت کسری گرد نمی شود، بلکه به سادگی دور ریخته می شود.
  • نوع بولی به هیچ یک از انواع ریخته نمی شود.
  • نوع کاراکتر به انواع عددی ریخته می شود، مانند یک کد کاراکتر در سیستم یونیکد.
  • اگر عدد بزرگتر از ظرف آن باشد، نتیجه غیر قابل پیش بینی خواهد بود.

این مقاله تنها بخشی از مطالب را در مورد موضوع ریخته گری نوع توصیف می کند. همچنین ریخته‌گری‌های نوع شی، ریخته‌گری رشته‌ای (به هر حال، هر چیزی را می‌توان در رشته نوشت، درست است؟)، و ارتقای نوع خودکار در عبارات نیز وجود دارد.

امیدواریم مقاله ما برای شما مفید بوده باشد. همچنین امکان ثبت نام در دوره های جاوا ما در کیف وجود دارد. ما از صفر تمرین می کنیم. اطلاعات دقیقمی توانید ما را در پیدا کنید.


برترین مقالات مرتبط