نحوه راه اندازی گوشی های هوشمند و رایانه های شخصی. پرتال اطلاعاتی

تبدیل جاوا دو برابر به int. مثال

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

تبدیل نوع T 1 به نوع T 2 اجازه می دهد تا بیانی از نوع T 1 در زمان کامپایل به عنوان بیانی از نوع T 2 در نظر گرفته شود. در برخی موارد، این یک ساختار صرفاً نحوی است که بر کد تولید شده تأثیر نمی گذارد؛ در موارد دیگر، تبدیل نوع نیاز دارد اقدامات اضافیدر طول دوره اجرا برای تغییر مقدار عبارت یا بررسی های اضافی برای صحت تبدیل اعمال شده. مثال ها:

  • تبدیل نوع بین المللیدر هر نوع طولانیبه یک عدد صحیح 32 بیتی نیاز دارد تا در زمان اجرا به یک عدد صحیح 64 بیتی بسط داده شود. هیچ از دست دادن اطلاعات در این مورد وجود ندارد.
  • تبدیل نوع شناوردر هر نوع طولانیدر زمان اجرا نیاز به تبدیل غیر ضروری یک مقدار شناور 32 بیتی به یک عدد صحیح 64 بیتی دارد. بسته به مقدار اولیه، از دست دادن اطلاعات ممکن است رخ دهد یا نباشد.
  • تبدیل از Thread به Object ساده است: از آنجا که کلاس Thread از نسل Object است، هر ارجاعی به یک شی از نوع Thread به طور خودکار مرجعی به یک شی از نوع Object است.
  • تبدیل از Object به Thread به بررسی زمان اجرا نیاز دارد. اگر مرجعی که تبدیل می شود در واقع یک مرجع به یک شی از نوع Thread باشد، آنگاه به عنوان نتیجه تبدیل برگردانده می شود، در غیر این صورت یک استثنا ایجاد می شود.

5.4.1.1. گسترش تبدیل اعداد

گسترش تبدیل اعدادتبدیل های یک نوع عددی به یک نوع عددی "بزرگتر" هستند که ایمن در نظر گرفته می شوند زیرا ارزش مقدار تبدیل شده را از دست نمی دهند. چنین تبدیل‌هایی در جاوا عبارتند از:

  • تحولات بایتکه در کوتاه, بین المللی, طولانی, شناورو دو برابر;
  • تحولات کوتاهکه در بین المللی, طولانی, شناورو دو برابر;
  • تحولات کاراکترکه در بین المللی, طولانی, شناورو دو برابر;
  • تحولات بین المللیکه در طولانی, شناورو دو برابر;
  • تحولات طولانیکه در شناورو دو برابر;
  • تحولات شناورکه در دو برابر.

در واقع، تبدیل یک مقدار صحیح به یک مقدار شناور می تواند منجر به از دست دادن دقت شود، یعنی از دست دادن مقدار ارقام قابل توجه. بنابراین مثال بعدی

آزمون کلاس (اصلی خالی استاتیک عمومی (آرگس رشته) (int bigNumber = 1234567890؛ float approximate = bigNumber؛ System.out.println (تقریبی)؛ )

رشته 1234567936 را نمایش می دهد. این به دلیل این واقعیت است که هنگام تبدیل بین المللیکه در شناورمقدار به دست آمده 1.2345679E9 است به دلیل این واقعیت که مانتیس اعدادی مانند شناورفقط 8 رقم اعشاری (در اینجا برای عملکرد صحیحباید از تبدیل نوع استفاده شود دو برابر). با این حال، سیستم زمان اجرا هرگز هنگام انجام تبدیل های فهرست شده خطا ایجاد نمی کند.

5.4.1.2. تبدیل های باریک اعداد

تبدیل های باریک اعدادتبدیل از یک نوع عددی به یک نوع عددی "کوچکتر" است که می تواند منجر به از دست دادن اندازه و همچنین از دست دادن دقت شود. چنین تبدیل‌هایی در جاوا عبارتند از:

  • تحولات بایتکه در کاراکتر;
  • تحولات کوتاهکه در بایتو کاراکتر;
  • تحولات بین المللیکه در بایت, کوتاهو کاراکتر;
  • تحولات طولانیکه در بایت, کوتاه, بین المللیو کاراکتر;
  • تحولات شناورکه در بایت, کوتاه, بین المللی, طولانیو کاراکتر;
  • تحولات دو برابرکه در بایت, کوتاه, بین المللی, طولانی, شناورو کاراکتر;

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

5.4.1.3. گسترش تبدیل پیوند

گسترش تبدیل پیوندتبدیل انواع مرجع مشتق شده به انواع اجدادی خود هستند که نیازی به عمل در زمان اجرا ندارند و هرگز خطا ایجاد نمی کنند. چنین تبدیل‌هایی در جاوا عبارتند از:

  • تبدیل هر کلاس یا رابط به جد خود (به ویژه به نوع Object)؛
  • تبدیل کلاس به رابطی که پیاده سازی می کند.
  • تبدیل هر آرایه به نوع Object یا نوع Cloneable.
  • تبدیل آرایه ای از نوع S به آرایه ای از نوع T اگر S و T از انواع مرجع باشند و تبدیل از S به T در حال گسترش باشد.
  • تبدیل یک نوع تهی به هر نوع مرجع.

5.4.1.4. تبدیل پیوندهای باریک

تبدیل پیوندهای باریکتبدیل انواع مرجع مشتق شده به انواع فرزندان آنها است. این تبدیل‌ها به بررسی مشروعیت زمان اجرا نیاز دارند و ممکن است یک ClassCastException ایجاد کنند. چنین تبدیل‌هایی در جاوا عبارتند از:

  • تبدیل هر کلاس به نسل آن (به ویژه، تبدیل نوع Object به هر کلاس دیگر).
  • تبدیل یک کلاس به یک رابط زمانی که کلاس نهایی نیست و رابط داده شده را پیاده سازی نمی کند (به ویژه، تبدیل نوع Object به هر رابط).
  • تبدیل نوع Object به هر آرایه ای.
  • تبدیل هر رابط به کلاسی که نهایی نیست.
  • تبدیل هر رابط به کلاسی که نهایی است و این رابط را پیاده سازی می کند.
  • تبدیل رابط J به رابط K، زمانی که J از نسل K نیست، و هیچ روشی در هر دو J و K با امضای یکسان اما انواع نتایج متفاوت وجود ندارد.
  • تبدیل از آرایه ای از نوع S به آرایه ای از نوع T اگر S و T انواع مرجع باشند و تبدیل از S به T در حال باریک شدن باشد.

5.4.1.5. تبدیل رشته ها

هر عبارت در جاوا، از جمله خالی، می تواند به نوع String تبدیل شود.

5.4.1.6. تبدیل های نامعتبر

تبدیل نوع زیر در جاوا ممنوع است:

  • تبدیل هر نوع مرجع به هر نوع اولیه؛
  • تبدیل هر نوع اولیه به هر نوع مرجعی غیر از String.
  • تبدیل نوع تهی به هر نوع ابتدایی.
  • تبدیل به نوع یا نوع پوچ بولی;
  • تبدیل نوع بولیبه هر نوع دیگری غیر از String ;
  • تبدیل یک کلاس به کلاس دیگر در صورتی که هیچ یک از آنها اجداد دیگری نباشد (به جز تبدیل به نوع String).
  • اگر کلاس نهایی باشد و اجرا نشود، یک کلاس را به یک رابط تبدیل کنید رابط داده شده;
  • تبدیل کلاس به آرایه در صورتی که کلاس Object نباشد.
  • تبدیل یک اینترفیس به کلاسی که نهایی است و رابط داده شده را پیاده سازی نمی کند (به غیر از تبدیل به نوع String).
  • تبدیل رابط J به رابط K اگر روشی در هر دو J و K با امضای یکسان اما انواع نتایج متفاوت وجود داشته باشد.
  • تبدیل یک آرایه به کلاسی غیر از Object و String.
  • تبدیل آرایه به رابطی غیر از Cloneable.
  • تبدیل آرایه ای از نوع S به آرایه ای از نوع T در صورتی که تبدیل از S به T ممنوع باشد.

5.4.2. زمینه های تحول

5.4.2.1. تبدیل تکلیف

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

  • متغیر دارای نوع است بایت, کوتاهیا کاراکتر;
  • مقدار عبارت یک نوع ثابت است بین المللی، که در محدوده قرار می گیرد مقادیر ممکنمتغیر.

به عنوان مثال، عبارت x = 123; معتبر است، از نوع ثابت 123 (از نوع بین المللی) در محدوده قرار دارد مقادیر مجازنوع بایت.

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

s کوتاه = 123; char c = s; // یک خطای کامپایل ایجاد می کند

به دلیل انواع کاراکترو کوتاهطبق تعاریف بالا با انتساب ناسازگار هستند (اولی به عنوان کلمات 16 بیتی بدون علامت اجرا می شود و دومی امضا شده است).

5.4.2.2. تبدیل آرگومان های روش

تبدیل آرگومان های روشزمانی اتفاق می‌افتد که مقادیر آرگومان واقعی به نوع پارامترهای متد یا سازنده هنگام فراخوانی تبدیل می‌شوند. در این حالت، تبدیل نوع گسترده (اعم از عددی و مرجع) همیشه امکان پذیر است و تبدیل محدود مجاز نیست. دلایل آخرین ممنوعیت را می توان توضیح داد مثال زیر:

آزمون کلاس ( int static m(byte a, int b) ( return a + b; ) static int m(short a, short b) ( return a - b; ) public static void main (string args) ( System.out. println( m (1، 2)) // یک خطای کامپایل ایجاد می کند ) )

در اینجا کلاس Test شامل دو متد به همین نام است که فقط در انواع پارامترها با هم تفاوت دارند. اگر تبدیل آرگومان های باریک در جاوا مجاز باشد، زمان اجرا باید تعیین کند که فراخوانی m(1, 2) به کدام یک از این روش ها اشاره دارد. برای جلوگیری از چنین ابهاماتی، طراحان زبان مشکل را به طور اساسی حل کردند: آنها فراخوانی چنین روشی را ممنوع کردند. در این شرایط، برای فراخوانی، به عنوان مثال، متد اول، باید به صراحت نوع عملوند اول را مشخص کنیم (دوم از قبل دارای نوع بین المللی، یعنی m((بایت)1، 2) .

5.4.2.3. تبدیل به رشته

تبدیل به رشتهفقط در یک مورد اتفاق می افتد: زمانی که عملیات باینری + روی دو عملوند اعمال می شود که یکی از آنها از نوع String است. در این شرایط، عملوند دوم نیز به نوع String تبدیل می‌شود و نتیجه عملیات، الحاق رشته‌های حاصل است. این فرآیند با جزئیات بیشتر در فصل توضیح داده شده است. 5.14.

5.4.2.4. تبدیل نوع صریح

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

5.4.3. نوع تبدیل عملوندهای عددی

تبدیل نوع در حین ارزیابی عبارات عددییک سری ویژگی دارد. آنها به دو مورد می رسند: تبدیل عملوند در عملیات یکنواخت و در عملیات باینری.

قبل از اعدام عملیات یکنواخت:

  • اگر عملوند از نوع باشد بایت, کوتاهیا کاراکتر، به نوع تبدیل می شود بین المللی;
  • در غیر این صورت نوع آن تغییر نمی کند.

قبل از انجام عملیات باینری:

  • اگر یکی از عملوندهای نوع باشد دو برابر، سپس دومی نیز به نوع تبدیل می شود دو برابر;
  • شناور، سپس دومی نیز به نوع تبدیل می شود شناور;
  • در غیر این صورت، اگر یکی از عملوندهای نوع طولانی، سپس دومی نیز به نوع تبدیل می شود طولانی;
  • در غیر این صورت، هر دو عملوند به نوع تبدیل می شوند بین المللی.

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

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

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

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

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

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

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

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

تحول گسترده ( تبدیل گسترده) زمانی اتفاق می‌افتد که یک مقدار از یک نوع به یک نوع گسترده‌تر، با دامنه وسیع‌تری از مقادیر معتبر تبدیل می‌شود. جاوا تبدیل‌های گسترده‌ای را به‌طور خودکار انجام می‌دهد، برای مثال اگر یک نوع واقعی از نوع int را اختصاص دهید متغیر نوعدو برابر یا مقدار متغیری از نوع 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;

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

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

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

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

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

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

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

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

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

کلاس A (int x = 2; // فیلد والد) کلاس B A را گسترش می دهد (int x = 3؛ // فیلدی که باید با int والد y = 5 همپوشانی داشته باشد؛ // فیلدی که در کلاس والد نیست. ) آزمون کلاس ( public static void main (string args) ( A ab = new B(); // تحول رو به بالا System.out.println("Int x = " + ab.x); ))

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

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

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

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

کلاس D( public void doSome()( //Nonstatic method System.out.println("Nonstatic doSome from D"); ) public static void Action()( //Static method System.out.println("Static Action from D "); ) ) کلاس عمومی Okey گسترش می دهد D( public void doSome()( System.out.println("doSome from Okey"); ) public static void Action()( System.out.println("Static Action from Okey" )؛ ) public void main(string args) (D o=new Okey(); o.doSome(); //از کلاس Okey o.Action(); //از کلاس D) )

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

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

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

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

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

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

گاهی اوقات موقعیت هایی پیش می آید که شما ارزش برخی را دارید نوع خاصی، و باید آن را به متغیری از نوع دیگر اختصاص دهید. برای برخی از انواع، این می تواند بدون ریخته گری نوع انجام شود، در چنین مواردی از تبدیل نوع خودکار صحبت می شود. در جاوا، تبدیل خودکار تنها زمانی امکان پذیر است که نمایش عددی متغیر مقصد به اندازه کافی دقیق باشد که مقدار اصلی را حفظ کند. چنین تبدیلی رخ می دهد، برای مثال، زمانی که یک ثابت تحت اللفظی یا مقدار یک متغیر از نوع byte یا short وارد متغیری از نوع int می شود. نامیده می شود افزونه (گسترده شدن) یا افزایش دادن (ترویج), زیرا نوع عمق بیت کوچکتر به یک نوع سازگار بزرگتر گسترش می یابد (بالا می رود). اندازه نوع int همیشه به اندازه کافی بزرگ است تا اعداد را از محدوده مجاز برای نوع بایت ذخیره کند، بنابراین در موقعیت های مشابههیچ اپراتور بازیگری واضحی مورد نیاز نیست. عکس آن در بیشتر موارد درست نیست، بنابراین باید از عملگر cast برای ریختن مقدار int به متغیر بایت استفاده شود. این روش گاهی اوقات نامیده می شود باریک شدن (باریک شدن), زیرا شما صریحاً به مترجم می گویید که مقدار باید به متغیری از نوع مورد نظر شما تبدیل شود. برای فرستادن یک مقدار به یک نوع خاص، قبل از آن نوع محصور در پرانتز قرار دهید. قطعه کد زیر ارسال یک نوع منبع (یک متغیر int) را به یک نوع مقصد (یک متغیر بایت) نشان می‌دهد. اگر در طی چنین عملیاتی مقدار عدد صحیح خارج از محدوده مجاز برای نوع بایت بود، با تقسیم مدول به محدوده مجاز برای بایت کاهش می یابد (نتیجه تقسیم مدول بر یک عدد باقیمانده تقسیم بر این عدد است) ،

int a = 100;
بایتb = (بایت) a;

2.2.1. تبدیل خودکار نوع در عبارات

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

بایت الف = 40;
بایت b = 50;
بایت با = 100;
int d = a* b / c;

نتیجه عبارت میانی (a * b) ممکن است فراتر از محدوده مقادیر مجاز برای نوع بایت باشد. به همین دلیل جاوا به طور خودکار هر قسمت از عبارت را به int ارتقا می دهد، بنابراین جایی برای نتیجه میانی (a*b) وجود دارد.

تبدیل خودکار نوع گاهی اوقات می تواند باعث ایجاد پیام های خطای غیرمنتظره کامپایلر شود. برای مثال، کدی که در زیر نشان داده شده است، اگرچه کاملاً صحیح به نظر می رسد، اما در مرحله ترجمه پیام خطا ایجاد می کند. در آن، ما سعی می کنیم مقدار 50 * 2 را که باید کاملاً با نوع بایت مطابقت داشته باشد را در یک متغیر بایت بنویسیم. اما به دلیل تبدیل خودکار نوع نتیجه به int، یک پیام خطایی از مترجم دریافت می کنیم - از این گذشته، هنگام تبدیل یک int به بایت، ممکن است از دست دادن دقت رخ دهد.

بایت b = 50;
b = b*2:
^ نوع ناسازگار برای =. برای تبدیل int به بایت نیاز به ریخته گری واضح است.
(نوع ناسازگار برای =. تبدیل صریح مورد نیاز استبهبایت)

متن تصحیح شده:
بایتb = 50;
b = (بایت) (b*2)؛

که باعث می شود b با مقدار صحیح 100 پر شود.

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

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

ارتقاء کلاس(
اصلی خالی استاتیک عمومی (رشته آرگ)(
بایت=42;
کاراکتر با= "a';
شورت = 1024;
int i = 50000;
float f = 5.67f;
دو برابر شد=.1234;
نتیجه مضاعف = (f*b) + (i/c) - (d*s);
سیستم، خارج println ((f* b)+ "+ "+ (i / c)+ "-" + (d*s));
سیستم، خارج println("result = "+result); )
}

عبارت فرعی f*b یک شناور ضرب در یک بایت است، بنابراین به طور خودکار به شناور ارتقا می یابد. نوع عبارت فرعی i/c بعدی (int تقسیم بر char) به int ارتقا می یابد. به طور مشابه، عبارت فرعی d*s (دو برابر ضربدر کوتاه) به دو برابر ارتقا می یابد. در مرحله بعدی محاسبات، با سه نتیجه میانی از انواع float، int و double روبرو هستیم. ابتدا، وقتی دو مورد اول اضافه می شوند، نوع int به شناور ارتقا می یابد و نتیجه یک نتیجه شناور است. وقتی یک مقدار دو برابر از آن کم می کنیم، نوع نتیجه به دو برابر ارتقا می یابد. نتیجه نهایی کل عبارت یک مقدار دو برابر است.

اکنون که همه انواع ساده از جمله اعداد صحیح، واقعی، نمادها و بولی ها را دیدیم، بیایید سعی کنیم همه اطلاعات را با هم جمع کنیم. مثال زیر برای هر یک از متغیرها ایجاد می کند انواع سادهو مقادیر این متغیرها نمایش داده می شود.

کلاس SimpleTypes(
اصلی خالی استاتیک عمومی (رشته آرگ) (
بایت b = 0x55;
s کوتاه = 0x55ff;
int i = 1000000;
طولانی l = 0xffffffffL;
کاراکتر با= 'a';
float f= .25f;
دو برابر d = 0.00001234;
boolean bool = درست;
System.out.println("byte b = " + b);
System.out.println("s short = " +s);
System.out.println("int i =" + i);
System.out.println("long 1 = " + l);
System.out.println("char with=” + با);
System.out.println("float f =" + f);
System.out.println("double d = " + d);
System.out.println("boolean bool =" + bool); )
}

هنگامی که این برنامه را اجرا می کنید، باید خروجی زیر را دریافت کنید:

بایت b = 85
شورت = 22015
int i = 1000000
طول 1 = 4294967295
کاراکتر با= a
شناور f = 0.25
دو برابر d=1.234e-005
بولی بولی = درست است

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

آخرین به روز رسانی: 1397/10/29

هر یک نوع پایهداده ها تعداد معینی از بایت حافظه را اشغال می کنند. این محدودیتی را برای عملیاتی که در آن انجام می شود اعمال می کند انواع متفاوتداده ها. به مثال زیر توجه کنید:

int a = 4; بایت b = a; //! خطا

در این کد با خطا مواجه خواهیم شد. اگرچه هر دو نوع بایت و نوع int نشان دهنده اعداد صحیح هستند. علاوه بر این، مقدار متغیر a که به متغیری از نوع بایت اختصاص داده می شود، کاملاً در محدوده مقادیر برای نوع بایت (از 128- تا 127) قرار می گیرد. با این حال، با یک خطای زمان کامپایل مواجه می شویم. زیرا در این حالت سعی داریم داده هایی را که 4 بایت اشغال می کند به متغیری که فقط یک بایت می گیرد اختصاص دهیم.

با این حال، برنامه ممکن است نیاز داشته باشد که چنین تبدیلی انجام شود. در این مورد، من باید از عملیات تبدیل نوع (عملیات ()) استفاده کنم:

int a = 4; بایت = (بایت)a; // نوع تبدیل: از نوع int به نوع بایت System.out.println(b); // چهار

عملیات تبدیل نوع شامل تعیین نوع تبدیل مقدار در داخل پرانتز است. به عنوان مثال، در مورد عملیات (byte)a، نوع داده int به نوع بایت تبدیل می شود. در نتیجه، مقداری از نوع بایت دریافت می کنیم.

تبدیل صریح و ضمنی

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

تبدیل های خودکار

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

بدون هیچ مشکلی به صورت اتوماتیک تولید می شود گسترش تحولات(گسترش) - آنها نمایش یک شی را در حافظه گسترش می دهند. مثلا:

بایت b = 7; int d = b; // تبدیل از بایت به int

در این حالت مقداری از نوع بایت که 1 بایت در حافظه اشغال می کند به نوع int که 4 بایت را اشغال می کند گسترش می یابد.

تبدیل‌های خودکار گسترش‌یافته با زنجیره‌های زیر نشان داده می‌شوند:

byte -> short -> int -> long

int -> double

کوتاه -> شناور -> دو برابر

char -> int

از دست دادن خودکار تبدیل های دقیق

برخی از تبدیل ها را می توان به طور خودکار بین انواع داده با عمق بیت یکسان، یا حتی از نوع داده با عرض بیت بیشتر به نوع داده با عرض بیت کمتر انجام داد. اینها زنجیره‌های تبدیل زیر هستند: int -> float، long -> float و long -> double بدون خطا تصادفی می‌شوند، اما ممکن است در طول تبدیل با از دست دادن اطلاعات مواجه شویم.

مثلا:

Int a = 2147483647; شناور b = a; // از نوع int به نوع شناور System.out.println(b); // 2.14748365E9

تبدیل های صریح

در سایر تبدیل‌های نوع اولیه، عملیات تبدیل نوع به صراحت اعمال می‌شود. معمولاً اینها تبدیل‌های باریک (باریک شدن) از نوع با عمق بیت بیشتر به نوع با عرض بیت کمتر هستند:

طولانی a = 4; int b = (int) a;

از دست دادن اطلاعات در هنگام تبدیل

هنگام اعمال تبدیل های صریح، ممکن است با از دست دادن داده ها مواجه شویم. برای مثال کد زیر برای ما مشکلی ایجاد نمی کند:

Int a = 5; بایت b = (بایت) a; System.out.println(b); // 5

عدد 5 به خوبی در محدوده مقادیر نوع بایت قرار می گیرد، بنابراین پس از تبدیل، متغیر b برابر با 5 خواهد بود. اما در صورت زیر چه اتفاقی می افتد:

Int a = 258; بایت b = (بایت) a; System.out.println(b); // 2

نتیجه عدد 2 خواهد بود. در این حالت، عدد 258 برای نوع بایت خارج از محدوده است (از 128- تا 127)، بنابراین مقدار کوتاه می شود. چرا نتیجه دقیقاً عدد 2 است؟

عدد a که 258 است در سیستم دودوییبرابر با 00000000 00000000 00000001 000000010 خواهد بود. مقادیر نوع بایت تنها 8 بیت در حافظه اشغال می کنند. از همین رو نمایش باینری int به 8 رقم راست کوتاه شده است، یعنی 00000010، که در سیستم اعشاریعدد 2 را می دهد.

برش اعداد گویا به اعداد صحیح

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

Double a = 56.9898; intb = (int)a;

در اینجا مقدار b 56 خواهد بود، حتی اگر 57 به 56.9898 نزدیکتر باشد. برای جلوگیری از چنین حوادثی باید از تابع گرد کردن استفاده کرد که در کتابخانه ریاضیجاوا:

Double a = 56.9898; int b = (int)Math.round(a);

تحولات معاملات

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

    اگر یکی از عملوندهای عملیات از نوع double باشد، عملوند دوم نیز به نوع double تبدیل می شود.

    اگر شرط قبلی برقرار نباشد و یکی از عملوندهای عملیات از نوع float باشد، عملوند دوم به نوع float تبدیل می شود.

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

    در غیر این صورت، تمام عملوندهای عملیات به نوع int تبدیل می شوند

نمونه های تبدیل:

Int a = 3; دو برابر b = 4.6; دو برابر c = a+b;

از آنجایی که مقدار دوتایی در عملیات دخیل است، مقدار دیگر نیز به نوع دوگانه ریخته می شود و مجموع دو مقدار a + b نشان دهنده نوع دوگانه خواهد بود.

مثالی دیگر:

بایت a = 3; کوتاه b = 4; بایت c = (بایت) (a+b);

دو متغیر از نوع byte و short (نه double، float یا long)، بنابراین هنگام اضافه شدن به نوع int تبدیل می شوند و مجموع a+b آنها یک مقدار int را نشان می دهد. بنابراین، اگر این مجموع را به متغیری از نوع بایت اختصاص دهیم، دوباره باید یک نوع تبدیل به بایت انجام دهیم.

اگر داده های نوع char در عملیات دخیل باشند، به int تبدیل می شوند:

Int d = "a" + 5; System.out.println(d); // 102

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