Преобразуване на тип данни в java. Преобразуване на примитивни типове в Java

Java е строго типизиран език за програмиране, което означава, че всеки израз и всяка променлива има строго дефиниран тип по време на компилиране.
Видове отливки
Java предоставя седем типа cast:

  • самоличност;

  • Разширяване на примитивен тип (разширяващ примитив);

  • стеснителен примитивен тип (стеснителен примитив);

  • Разширение на типа обект (разширяваща препратка);

  • Стесняване на типа на обекта (препратка за стесняване);

  • Преобразуване в низ (String);

  • Забранени преобразувания (забранени);
Нека ги разгледаме отделно.
Трансформация на идентичността
Най-простата е трансформацията на идентичността. В Java преобразуването на израз от всякакъв тип в абсолютно същия тип винаги е законно и е успешно.
Това е важно, за да може теоретично да се твърди, че всеки тип в Java може да участва в преобразуване, дори и да е идентичен.
Преобразуване на примитивни типове (разширяване и стесняване)
За прости типове разширяването означава, че се извършва преход от по-малко обемен тип към по-вместим. Например от тип байт (дължина 1 байт) до тип int (дължина 4 байта). Такива преобразувания са безопасни в смисъл, че новият тип винаги е гарантиран, че съдържа всички данни, които са били съхранени в стария тип, и по този начин няма загуба на данни. Ето защо компилаторът го прилага сам, незабележимо за разработчика:

byteb=3;
int a=b;

Следните 19 трансформации се разширяват:

  • От байт към кратко, int, дълго, плаващо, двойно

  • От кратко към int, дълго, плаващо, двойно

  • От char до int, long, float, double

  • От int до long, float, double

  • От дълги до плаващи, удвоени

  • плува, за да се удвои
Обърнете внимание, че не можете да конвертирате в char от типове с по-малка или равна дължина (байт, къса) или, обратно, в short от char без загуба на данни. Това се дължи на факта, че char, за разлика от други типове цели числа, е подписан.
Въпреки това, трябва да се помни, че дори и при разширяване, данните все още могат да бъдат изкривени. Това са прехвърляния от стойности int към float и прехвърляния от дълги стойности към float или double. Въпреки че тези дробни типове могат да приемат много по-големи числа от съответните цели числа, те имат по-малко значими цифри.
Например:

дълго a = 111111111111L;
float f=a;
a=(дълго)f; // () е просто операция за преобразуване на тип
System.out.println(a); //резултат 111111110656

Обърнете внимание - стесняване - означава, че преходът се извършва от по-вместим тип към по-малко вместителен. При такова преобразуване съществува риск от загуба на данни. Например, ако едно int е било по-голямо от 127, тогава когато се прехвърля към байт, битовите стойности, по-стари от осми, ще бъдат загубени. В Java такова преобразуване трябва да се направи изрично, т.е. програмистът в кода трябва изрично да посочи, че възнамерява да извърши такова преобразуване и е готов да загуби данни.
Следните 23 трансформации се стесняват:

  • от байт към символ

  • От кратко към байт, char

  • От символ до байт, кратко

  • От int до байт, кратко, char

  • От дълго към байт, кратко, char, int

  • От float до байт, short, char, int, long

  • От двоен към байт, short, char, int, long, float
Когато стеснявате целочислен тип до по-тесен целочислен тип, всички битове от висок ред, които не се вписват в новия тип, просто се изхвърлят. Не се извършват закръгляване или други действия за получаване на по-правилен резултат:

System.out.println((байт)383);
System.out.println((байт)384);
System.out.println((байт)-384);

Резултатът ще бъде:

127
-128
-128
Вижда се, че знаковият бит не е имал никакъв ефект по време на стесняване, тъй като просто е бил изхвърлен - резултатът от хвърлянето на реципрочните числа (384, -384) се оказва един и същ. Следователно може да се загуби не само точната абсолютна стойност, но и знакът на количеството.
Това важи и за char:

char c=4000;
System.out.println((short)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 могат да сочат само към обекти от точно същия тип. Сега можем да преминем към преобразуване на референтни типове въз основа на такова дърво на наследяване.
Разширяването означава преминаване от по-специфичен тип към по-малко специфичен тип, т.е. преход от деца към родители. Подобно на случая с примитивните типове, този преход се извършва от самата 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 екземпляр на ChildY)(
ChildYcy = (ChildY)p;
}

Родител p2=newChildZ();
if (p2 екземпляр на ChildY) (
ChildYcy = (ChildY)p2;
}

Родител p3=нов родител();
if (p3 instanceofChildY)(
ChildYcy = (ChildY)p3;
}

В този пример няма да има грешки. Първата трансформация е възможна и ще бъде извършена. Във втория и третия случаи условията на операторите if няма да работят и следователно няма да има неправилен преход.
Преобразуване в низ
Всеки тип може да бъде прехвърлен към низ, т.е. към екземпляр на класа String. Такова преобразуване е изключително поради факта, че обхваща абсолютно всички видове.
Различните типове се преобразуват в низ, както следва:

  • Числовите типове се записват в текстова форма без загуба на точност на представяне. Първо, въз основа на примитивната стойност, се генерира екземпляр на съответния клас „обвивка“, след което методът toString() се извиква върху него. Но тъй като тези действия са невидими отвън, JVM ги оптимизира и преобразува примитивните стойности директно в текст.

  • Булевите стойности се прехвърлят към низа "true" или "false" в зависимост от стойността.

  • За стойностите на обекта се извиква методът toString(). Ако методът върне null, тогава резултатът ще бъде низът "null".

  • За нулева стойност се генерира низът "null".
Забранени преобразувания
Не всички преходи между произволни типове са разрешени. Например, забранените преобразувания включват: преходи от всеки референтен тип към примитивен и обратно (с изключение на преобразуване в низ), булевите могат да бъдат прехвърлени само към този тип или към низ. Освен това е невъзможно да се донесат един на друг класове, разположени на съседни клони на дървото на наследяването. В примера, за който се смяташе, че илюстрира референтни типове, преходът от ChildY към ChildZ е забранен.
Този списък със забранени трансформации не е изчерпан. Той е доста широк и в същото време всички опции са доста очевидни, така че няма да бъдат разглеждани подробно. Желаещите могат да получат пълна информация от спецификацията.
Разбира се, опит за извършване на забранено преобразуване ще доведе до грешка.

Използване на отливки
Ситуациите за преобразуване на типове могат да бъдат групирани, както следва:

  • Присвояване на стойности на променливи (присвояване). Не всички преходи са разрешени при такава трансформация - ограниченията са избрани по такъв начин, че да не може да се случи изключение.

  • Извикване на метод. Това преобразуване се прилага към аргументите на извикания метод или конструктор. Такова прехвърляне никога не генерира грешки. Прехвърлянето се извършва и при връщане на стойността на метода.

  • Изричен актьорски състав. В този случай изрично е посочено към кой тип искате да прехвърлите оригиналната стойност.

  • Операторът за конкатенация преобразува в низ от своите аргументи.

  • Числово разширение. Числовите операции може да изискват промяна на типа на аргумента(ите). Това преобразуване има специално име - разширено, тъй като изборът на целевия тип може да зависи не само от първоначалната стойност, но и от втория аргумент на операцията.
Задача №8
Добавете към проекта използването на cast за вашата йерархия на класа.

Завършихме последната си статия с факта, че ви обещах да ви кажа какви типове могат да се хвърлят и как се прави всичко това. Да започваме.

В ролятав аритметичните изрази се изпълнява автоматично.

byte->short->int->long->float->double

Ако операндите a и b се комбинират с двоичен оператор (ще обсъдим това по-долу), и двата операнда се преобразуват в данни от същия тип, преди да бъдат изпълнени, както следва:

  • Ако един от операторите е от тип double, вторият също се преобразува в double;
  • Ако един от операторите е от тип float, другият също се преобразува в float;
  • Ако един от операторите е от тип long, вторият също се преобразува в long;
  • Ако един от операторите е от тип int, другият също се преобразува в int;

Разрешени преобразувания на типове

Плътните линии показват трансформацията, извършена без загуба на информация. Това преобразуване се извършва имплицитно. Трансформациите, при които може да възникне загуба на информация, се наричат ​​кастинг. Те са показани с пунктирани линии. Ако няма линии към типа данни на фигурата, тогава такова преобразуване е невъзможно. Трансформациите със загуба на информация трябва да се извършват много внимателно. И така, как можете да загубите значителна част от данните и все пак програмата може да работи правилно.

За да стесните кастите, е необходимо да го направите изрично. Например: байт b = (байт)128; прехвърляне на int към тип байт.

Предлагам да направя няколко примера.

Може да не разбирате малко този код, тъй като все още не съм обяснил какво е компилатор, константи и т.н. По-нататък на обучението ще ви разкажа всичко, въпреки че трябваше да го направя по-рано. И сега искам да опиша какви правила трябва да имат имената на променливите.

  • Имената на променливите не могат да започват с цифра, не могат да се използват в имена като символи на аритметични и логически оператори, както и символа '#'.
  • Използването на символите „$“ или „_“ е приемливо, включително първата позиция и името.
  • Променлива от примитивен тип, декларирана като член на класа (глобална променлива), е настроена на нула по подразбиране.
  • Ако променлива е декларирана като локална променлива в метод, тя трябва да бъде инициализирана преди употреба. Тъй като локалните променливи не са инициализирани по подразбиране. Това означава, че не можете да декларирате локална променлива и да я оставите неинициализирана. Тоест така: int i;. Ако направите това в метод, компилаторът ще ви помоли да зададете стойност по подразбиране, докато чрез създаване на такава променлива като член на класа (глобален), самият компилатор ще я зададе на 0.
  • Обхватът и продължителността на живота на променливата са ограничени от блока (), в който е декларирана. Ако сте създали променлива вътре в метода (както направихме в примерите), тогава не можете да я използвате извън метода, тъй като методът е разделен със скоби (). Глобалната променлива се вижда във всички блокове.
  • Също така е забранено използването на запазени думи от java. Целият списък с ключови думи може да се види на снимката по-долу.

И тъй като в тази статия засегнах израза на двоичен оператор, предлагам да разгледаме операторите в Java. Освен това няма толкова много теории.

Java има няколко типа оператори: просто присвояване, аритметични, унарни, равни и релационни, условни, сравнение на типове, побитово и побитово изместване.

Много модни думи, но тази снимка ще обясни всичко много просто:

Първо ще използваме побитово сравнение, присвояване и постфиксни оператори. Други оператори не са толкова често срещани, така че ще разгледаме само тези, които ще използваме.

    публичен клас OperatorsInJava(

    int a = 5;

    int b = 6;

    int сума = a + b;

    int разлика = a - b;

Често има нужда от преобразуване на низове в стойности от други типове, като int или boolean, и обратно. По конвенция отговорността за преобразуването на низа vстойността на друг тип се присвоява на съответния метод от този тип. Така, например, преобразуването на низ в int стойност се извършва чрез статичен метод от класа на обвивката Integer. Следващата таблица изброява всички типове, които могат да преобразуват стойности в низове и обратно, и изброява съответните методи.

ТИП Метод за преобразуване Метод за преобразуване от низ

линия

boolean String.valueOf(boolean) new.Boolean(String). булева стойност()

байт String.valueOf(byte) Byte.parseByte(string, int)

short String.valueOf(short) Short.parseShort(string, int)

int String.valueOf(int) Integer.parseInteger(string, int)

long String.valueOf(long) Long.parseLong(String, int)

float String.valueOf(float) Float.parseFloat(String)

double String.valueOf(double) Double.parseDouble(String)

За да преобразувате низ в булева стойност, трябва да създадете булев обект и след това да заявите стойността му. Всички останали класове обвивки съдържат съответни методи анализирайте.Методи анализирайтецелочислените типове съществуват в две претоварени форми: първият, в допълнение към низа, изисква допълнителен аргумент от типа int, представляващ основата на бройната система - от 2 до 32; вторият приема само параметър на низ и по подразбиране е десетичен. Във всички случаи, с изключение на Boolean, допускането е, че ако низът представлява стойност, която не може да бъде правилно преобразувана в число от подходящия тип, се хвърля NumberFormatException. Класът Boolean следва конвенцията, че всеки параметърен низ, който не е равен на "true" (независимо от малки и малки букви), води до създаването на булев обект със стойност false.

Методи, които ви позволяват да конвертирате знаци, които са представени в една от поддържаните от езика форми (като \b, \uxxxxи т.н.) до стойност от тип char и обратно не съществува. За да получите String обект, съдържащ единичен знак, просто извикайте метода String.valueOf, като му предадете подходящата стойност на char като параметър.

Също така няма начини за създаване на низови представяния на числа, дадени в един от поддържаните от езика формати - с водеща нула (O), обозначаваща осмично число, и префикс Ox (или OX), който е знак за шестнадесетична бройна система. За разлика от тях, целочислените обвиващи класове поддържат версии на метода за декодиране, които могат да преобразуват низове в числови стойности от подходящ тип и да "разбират", че водещата 0 е осмична, а един от префиксите Ox ИЛИ Ox е шестнадесетичен.

Всеки клас на приложение може да осигури поддръжка за преобразуване на естествени обекти в низове и обратно, ако неговата декларация отменя метода toString по подходящ начин и предоставя специален конструктор, който създава обект на клас въз основа на низа, предаден като параметър. Също така имате на ваше разположение метода String.valueOf(Object obj), който връща или низовия обект „null“ (ако стойността на obj е null), или резултата от метода obj.toString. Класът String съдържа достатъчно претоварени версии на метода valueOf, за да ви позволи да конвертирате всяка стойност от всякакъв тип в String обект, като просто извикате valueOf с желания аргумент.

Понякога възникват ситуации, когато имате стойност от определен тип и трябва да я присвоите на променлива от различен тип. За някои типове това може да стане без преобразуване на типа, в такива случаи се говори за автоматично преобразуване на типа. В Java автоматичното преобразуване е възможно само когато цифровото представяне на променливата местоназначение е достатъчно точно, за да задържи оригиналната стойност. Такова преобразуване се случва, например, когато литерална константа или стойността на променлива от тип байт или кратко се въведе в променлива от тип int. Нарича се разширение (разширяване) или нараства (промоция), тъй като типът с по-малка битова дълбочина се разширява (повдига) до по-голям съвместим тип. Типът int винаги е достатъчно голям, за да задържи числа в диапазона, разрешен за типа байт, така че в такива ситуации не се изисква изричен оператор. Обратното не е вярно в повечето случаи, така че трябва да се използва оператор за прехвърляне, за да се прехвърли стойност int в байтова променлива. Тази процедура понякога се нарича стесняване (стесняване), защото вие изрично казвате на преводача, че стойността трябва да бъде преобразувана, за да се побере в променлива от типа, който искате. За да прехвърлите стойност към конкретен тип, предхождайте я с този тип, затворен в скоби. Кодовият фрагмент по-долу демонстрира прехвърляне на тип източник (променлива int) към тип дестинация (байт променлива). Ако по време на такава операция целочислената стойност е извън диапазона, позволен за типа байт, тя ще бъде намалена чрез деление по модул с разрешения диапазон за байт (резултатът от разделяне по модул с число е остатъкът от разделението с това число) ,

int a = 100;
байтb = (байт) а;

2.2.1. Автоматично преобразуване на типове в изрази

Когато се изчислява стойността на израз, прецизността, необходима за съхраняване на междинни резултати, често трябва да бъде по-голяма от тази, необходима за представяне на крайния резултат,

байт а = 40;
байт b = 50;
байт с = 100;
int d = a* b / c;

Резултатът от междинния израз (a * b) може да надхвърли диапазона от стойности, разрешени за типа байт. Ето защо Java автоматично насърчава всяка част от израза да въвежда int, така че има достатъчно място за междинния резултат (a*b).

Автоматичното преобразуване на типове понякога може да причини неочаквани съобщения за грешка на компилатора. Например кодът, показан по-долу, въпреки че изглежда доста правилен, води до съобщение за грешка по време на фазата на превод. В него се опитваме да запишем стойността 50 * 2, която трябва да се вписва идеално в типа байт, в байтова променлива. Но поради автоматичното преобразуване на типа на резултата в int, получаваме съобщение за грешка от преводача - в края на краищата, когато конвертирате int в байт, може да възникне загуба на прецизност.

байт b = 50;
b = b*2:
^ Несъвместим тип за =. Изрично привеждане е необходимо за преобразуване на int в байт.
(Несъвместим тип за =. Изисква се изрично преобразуванеint toбайт)

Коригиран текст:
байтb = 50;
b = (байт) (b*2);

което кара b да се запълни с правилната стойност от 100.

Ако изразът използва променливи от типове byte, short и int, тогава типът на целия израз автоматично се повишава до int, за да се избегне препълване. Ако типът на поне една променлива в израза е дълъг, тогава типът на целия израз също се повишава до дълъг. Не забравяйте, че всички целочислени литерали, които не завършват с L (или 1), са от тип int.

Ако изразът съдържа операнди от тип float, тогава типът на целия израз автоматично се повишава до float. Ако поне един от операндите е от тип double, тогава типът на целия израз се повишава до удвоен. По подразбиране Java третира всички литерали с плаваща запетая като тип double. Следващата програма показва как типът на всяка стойност в израз се повишава, за да съответства на втория операнд на всеки двоичен оператор.

клас Популяризиране (
public static void main(String args)(
byteb=42;
овъглявам с= "а";
шорти = 1024;
int i = 50000;
float f = 5,67f;
удвоено=.1234;
двоен резултат = (f*b) + (i/ c) - (d* s);
Система, навън. println ((f* b)+ "+ "+ (i / c)+ "-" + (d* s));
Система, навън. println("резултат = "+резултат); )
}

Подизразът f*b е float, умножен по байт, така че автоматично се повишава до float. Типът на следващия i/c подизраз (int, разделен на char) се повишава до int. По подобен начин подизразът d*s (двойно умножено по short) се повишава до удвояване. На следващата стъпка от изчисленията имаме работа с три междинни резултата от типове float, int и double. Първо, когато се добавят първите две, типът int се повишава до float и резултатът е float резултат. При изваждане на двойна стойност от него, типът на резултата се повишава до удвоен. Крайният резултат от целия израз е двойна стойност.

Сега, когато видяхме всички прости типове, включително цели числа, реални числа, символи и булеви, нека се опитаме да обединим цялата информация. Следващият пример създава променливи от всеки един от простите типове и показва стойностите на тези променливи.

клас SimpleTypes(
public static void main(String args) (
байт b = 0x55;
кратко s = 0x55ff;
int i = 1000000;
дълго l = 0xffffffffL;
овъглявам с= 'а';
float f= .25f;
двойно d = .00001234;
boolean bool = вярно;
System.out.println("байт b = " + b);
System.out.println("short s = " +s);
System.out.println("int i =" + i);
System.out.println("long 1 = " + l);
System.out.println("char с=” + с);
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
овъглявам с= а
float f = 0,25
двойно d=1,234e-005
boolean bool = вярно

Обърнете внимание, че целите числа се отпечатват в десетичен знак, въпреки че ние посочихме някои от тях в шестнадесетичен.

Посочена статия:

  • написано от екипа. Надяваме се, че ще ви бъде полезно. Приятно четене!
  • това е една от статиите от нашата

Преобразуването на типове е тема, която може да изглежда обезсърчителна за начинаещи Java програмисти. Въпреки това, ние ви уверяваме, че всъщност всичко е просто. Основното нещо да се разбере според какви закони протича взаимодействието между променливите и запомнете това, когато пишете програми. Така че, нека го разберем.

В Java има 2 вида трансформации - картинка, която да ви помогне:

Припомнете си, че цялата "Вселена на Java" се състои от:

  • примитивни типове (byte, short, int, long, char, float, double, boolean)
  • обекти

В тази статия ние:

  • помислете за преобразуване на типове за примитивни типове променливи
  • трансформацията на обекти (String, Scanner и др.) не се разглежда в тази статия, тъй като с обектите се случва отделна „магия“ - това е тема за отделна статия.
Автоматично преобразуване

Е, добре, нека се опитаме да разберем какво е "автоматично преобразуване".

Не забравяйте, че когато разглеждахме типовете променливи (в статията), казахме това променливата е някакъв вид "контейнер" A, който може да съхранява стойност за по-късна употреба в програмата. Говорихме и за факта, че всеки тип променлива има свой собствен диапазон от валидни стойности и количеството памет, която заема. Ето знака, където е написано:

Така че това е, към което всъщност стигаме. Освен това не ви беше никак лесно да ви бъдат дадени диапазони от валидни стойности и количеството заета памет 🙂

Нека сравним, например:

1. байт и кратък. byte има по-малък диапазон от валидни стойности от short. Тоест байтът е като по-малка кутия, а късата е по-голяма кутия. И това означава можем да вложим байт накратко.

2. байт и международен. byte има по-малък диапазон от валидни стойности от int. Тоест байтът е като по-малка кутия, а int е по-голяма кутия. И това означава можем да вложим байт в int.

3.int и дълги. int има по-малък диапазон от валидни стойности от long. Тоест int е като по-малка кутия, а long е по-голяма кутия. И това означава можем да вложим int в дълго.

Това е пример за автоматично преобразуване. Това може да бъде схематично изобразено под формата на следната снимка:

Нека да разгледаме как работи това на практика.

Пример №1

Код #1 - ако стартирате този код на вашия компютър,

class Test ( public static void main(String args) (байт a = 15; байт b = a; System.out.println(b); ) )

тест за клас (

байт a = 15;

байт b = a ;

Код #2 - ако стартирате този код на вашия компютър, конзолата ще покаже числото 15

class Test ( public static void main(String args) (байт a = 15; int b = a; System.out.println(b); ) )

тест за клас (

public static void main(String args)(

байт a = 15;

int b = a;

Система. навън . println(b);

И-и-и? Мислиш ли че пъти едно и също число е отпечатано на конзолата, и код #1 се различава от код #2 само по вида на променливата b тогава няма разлика между тях?Етова не е така.

Код №2 съдържа автоматиченпреобразуване на типа , но в код No 1 - не:

Въпреки че по същество числото е същото, но сега е в b Опо-голям контейнер, който заема повече дисково пространство. В този случай JVM извършва автоматични трансформации вместо вас. Тя знае това международенповече от байт .

В ролята

Друго нещо е, ако се опитвате да прехвърлите нещо от по-голям контейнер в по-малък.

Може да знаете, че по-голям контейнер съдържа нещо, което ще се побере в малък - но JVM не знае това и се опитва да ви предпази от грешки.

Следователно трябва да „кажете директно“, че ситуацията е под контрол:

Тест за клас ( public static void main(String args) (int a=0; long b=15; a = (int) b; ))

тест за клас (

public static void main(String args)(

int a = 0 ;

дълго b = 15 ;

a = (int ) b ;

Тук сме добавили (int)отпред б. Ако променливата абеше например байт, в скоби ще бъде (байт). Общата формула изглежда така:

Тя казва „направи с (по-голяма) стойност бпроменлива от типа (целеви), от който се нуждая международен ".

Ако нещо се обърка.

Досега разглеждахме ситуации, предполагайки, че знаем точно какво правим. Но какво ще стане, ако се опитате да поставите в контейнер нещо, което не се вписва там?

Оказва се, че в контейнера ще остане само това, което „приляга“. Например, дробната част на числата с плаваща запетая ще бъде "отсечена":

//пример 1 клас Тест ( public static void main(String args) ( double a=11.2345; int b=(int)a; System.out.println(b); // конзолата ще покаже числото 11 ))

//пример 1

тест за клас (

public static void main(String args)(

двойно a = 11,2345;

int b = (int) a;

Система. навън . println(b); // конзолата ще покаже числото 11

Трябва да се помни, че дробната част не е закръглена, а изхвърлени.

Но какво се случва, ако се опитаме да поставим число, което е извън границите? Например, ако в байт (обхват от байтове от -128 до 127) поставите числото 128? Мислиш ли, че ще получим 1? Не. Получаваме -128:

class Test ( public static void main(String args) ( double a=128; byte b=(byte)a; System.out.println(b); //ще видим -128 в конзолата))

Стойността на променлива може да се изчисли с това преобразуване, но целта на програмиста е да предотврати ситуации, при които стойността е извън границите, тъй като това може да доведе до неправилна работа на програмата.

задачи:
  1. Последователно запишете в компилатора преобразувания на всички примитивни типове един към друг, включително типове char и Направете таблица като тази:
байт къс char международен дълго плува двойно булев
байт
къс
char
международен
Дълго
плува
двойно
булев

На пресечната точка напишете: a - ако преобразуването се извършва автоматично, on - ако трябва да използвате изрично преобразуване, x - ако преобразуването не е възможно.

* се извиква прехвърляне на тип към себе си идентични- не е необходимо да се пише

  1. Вижте отново какъв размер е всеки примитивен тип. Опитайте се да направите блокова диаграма, показваща къде отиват кои типове. Плъзнете стрелките с надпис "разширяваща трансформация" и "стеснителна трансформация".
Въпроси

Когато интервюирате за позиция младши Java Developer, може да бъдете попитани:

Какво знаете за преобразуването на примитивни типове данни, има ли загуба на данни, възможно ли е да се преобразува булев тип?

Опитайте се да отговорите на въпроса.

Да обобщим:
  • Ако "поставите" съдържанието на по-малък контейнер в по-голям контейнер, преобразуването е автоматично и не трябва да възникват грешки.
  • Ако има нужда да поставите „стойност от по-голям контейнер в по-малък“, трябва да бъдете внимателни и да използвате изрично прехвърляне на типа.
  • При хвърляне на float или double към интегрални типове, дробната част не се закръглява, а просто се изхвърля.
  • Булевият тип не се прехвърля към нито един от типовете.
  • Типът char се прехвърля към числови типове, като символен код в системата UNICODE.
  • Ако числото е по-голямо от неговия контейнер, резултатът ще бъде непредсказуем.

Тази статия описва само част от материала по темата за отливане на типа. Има също така прехвърляния на типа на обекта, прехвърляне на низове (в края на краищата, всичко може да бъде написано в низ, нали?) и автоматично популяризиране на типа в изразите.

Надяваме се, че нашата статия е била полезна за вас. Възможно е също да се запишете в нашите курсове по Java в Киев. Тренираме от нулата. Можете да намерите подробна информация на нашия уебсайт.