Java приведение типов string к int. Преобразование типов

Иногда возникают ситуации, когда необходимо переменной одного типа присвоить значение переменной другого типа. Например:

Пример 1. Присвоение значения переменной одного типа другому

int i = 11; byte b = 22; i = b;

В Java существует 2 типа преобразований - автоматическое преобразование (неявное) и приведение типов (явное преобразование) .

1. Автоматическое преобразование

Рассмотрим сначала автоматическое преобразование. Если оба типа совместимы, их преобразование будет выполнено в Java автоматически. Например, значение типа byte всегда можно присвоить переменной типа int , как это показано в примере 1.

Для автоматического преобразования типа должно выполняться два условия:

  • оба типа должны быть совместимы
  • длина целевого типа должна быть больше длины исходного типа

В этом случае происходит преобразование с расширением .

Следующая схема показывает расширяющее преобразование в Java:

Сплошные линии обозначают преобразования, выполняемые без потери данных. Штриховые линии говорят о том, что при преобразовании может произойти потеря точности.

Например, тип данных int всегда достаточно велик, чтобы хранить все допустимые значения типа byte , поэтому никакие операторы явного приведения типов в данном случае не требуются. С точки зрения расширяющего преобразования числовые типы данных, в том числе целочисленные и с плавающей точкой, совместимы друг с другом. В то же время не существует автоматических преобразований числовых типов в тип char или boolean . Типы char и boolean также не совместимы друг с другом.

Стоит немного пояснить почему, к примеру тип byte не преобразуется автоматически (не явно) в тип char , хотя тип byte имеет ширину 8 бит, а char - 16, тоже самое касается и преобразования типа short в char . Это происходит потому, что byte и short знаковые типы данных, а char без знаковый. Поэтому в данном случае требуется использовать явное приведение типов, поскольку компилятору надо явно указать что вы знаете чего хотите и как будет обрабатываться знаковый бит типов byte и short при преобразовании к типу char .

Поведение величины типа char в большинстве случаев совпадает с поведением величины целого типа, следовательно, значение типа char можно использовать везде, где требуются значения int или long . Однако напомним, что тип char не имеет знака, поэтому он ведет себя отлично от типа short , несмотря на то что диапазон обоих типов равен 16 бит.

2. Приведение типов

Несмотря на все удобство автоматического преобразования типов, оно не в состоянии удовлетворить все насущные потребности. Например, что делать, если значение типа int нужно присвоить переменной типа byte ? Это преобразование не будет выполняться автоматически, поскольку длина типа byte меньше, чем у типа int . Иногда этот вид преобразования называется сужающим преобразованием , поскольку значение явно сужается, чтобы уместиться в целевом типе данных.

Чтобы выполнить преобразование двух несовместимых типов данных, нужно воспользоваться приведением типов. Приведение - это всего лишь явное преобразование типов. Общая форма приведения типов имеет следующий вид:

(целевой_тип) значение

где параметр целевой_тип обозначает тип, в который нужно преобразовать указанное значение.

Пример 2. Приведение типов

Например, в следующем фрагменте кода тип int приводится к типу byte :

Int i = 11; byte b = 22; b = (byte) i;

Пример 3. Преобразования значений с плавающей точкой в целые числа

Рассмотрим пример преобразования значений с плавающей точкой в целые числа. В этом примере дробная часть значения с плавающей точкой просто отбрасывается (операция усечения):

Double d = 3.89; int a = (int) d; //Результат будет 3

Пример 4. Преобразования более емкого целого типа к менее емкому целому числу

При приведении более емкого целого типа к менее емкому старшие биты просто отбрасываются:

Int i = 323; byte b = (byte) i; //Результат будет 67

Пример 5. Преобразования более емкого значения с плавающей точкой к менее емкому целому числу

При приведении более емкого значения с плавающей точкой в целое число происходит усечение и отбрасывание старших битов:

Double d = 389889877779.89; short s = (short) d; //Результат будет -1

3. Автоматическое продвижение типов в выражениях

Помимо операций присваивания, определенное преобразование типов может выполняться и в выражениях.

В языке Java действуют следующие правила:

  1. Если один операнд имеет тип double double .
  2. float , другой тоже преобразуется к типу float .
  3. Иначе, если один операнд имеет тип long , другой тоже преобразуется к типу long .
  4. Иначе оба операнда преобразуются к типу int .
  5. В выражениях совмещенного присваивания (+=,-=,*=,/=) нет необходимости делать приведение.

Приведем пример:

Пример 6. Автоматическое продвижение типов в выражениях

При умножении переменной b1 (byte ) на 2 (int ) результат будет типа int . Поэтому при попытке присвоить результат в переменную b2 (byte ) возникнет ошибка компиляции. Но при использовании совмещенной операции присваивания (*=), такой проблемы не возникнет.

Byte b1 = 1; byte b2 = 2 * b1; //Ошибка компиляции int i1 = 2 * b1; b2 *= 2;

Пример 7. Автоматическое продвижение типов в выражениях

В следующем примере тоже возникнет ошибка компиляции - несмотря на то, что складываются числа типа byte , результатом операции будет тип int, а не short.

Public class IntegerDemo1 { public static void main(String args) { byte b1 = 50, b2 = -99; short k = b1 + b2; //ошибка компиляции System.out.println("k=" + k); } }

Пример 8. Автоматическое продвижение типов в выражениях

Этот пример аналогичен предыдущему, но используется операция совмещенного присваивание, в которой приведение происходит автоматически.

Public class IntegerDemo2 { public static void main(String args) { byte b1 = 50, b2 = -99; b1 += b2; System.out.println("b1=" + b1); } }

Это достаточно большая тема, но мы постараемся рассмотреть ее как можно более полно и вместе с тем компактно. Частично мы уже касались этой темы когда рассматривали примитивные типы Java.

В Java возможны преобразования между целыми значениями и значениями с плавающей точкой. Кроме того, можно преобразовывать значения целых типов и типов с плавающей точкой в значения типа char и наоборот, поскольку каждый символ соответствует цифре в кодировке Unicode. Фактически тип boolean является единственным примитивным типом в Java, который нельзя преобразовать в другой примитивный тип. Кроме того, любой другой примитивный тип нельзя преобразовать в boolean.

Преобразование типов в Java бывает двух видов: неявное и явное .

Неявное преобразование типов выполняется в случае если выполняются условия:

  1. Оба типа совместимы
  2. Длина целевого типа больше или равна длине исходного типа

Во всех остальных случаях должно использоваться явное преобразование типов .

Так же существуют два типа преобразований:

  1. Расширяющее преобразование (widening conversion)
  2. Сужающее преобразование (narrowing conversion)

Расширяющее преобразование (widening conversion ) происходит, если значение одного типа преобразовывается в более широкий тип, с большим диапазоном допустимых значений. Java выполняет расширяющие преобразования автоматически, например, если вы присвоили литерал типа int переменной типа double или значение пепременной типа char переменной типа int. Неявное преобразование всегда имеет расширяющий тип .

Но у тут могут быть свои небольшие грабельки. Например если преобразуется значение int в значение типа float. И у значения int в двоичном представлении больше чем 23 значащих бита, то возможна потеря точности, так как у типа float под целую часть отведено 23 бита. Все младшие биты значения int, которые не поместятся в 23 бита мантиссы float, будут отброшены, поэтому хотя порядок числа сохраниться, но точность будет утеряна. То же самое справедливо для преобразования типа long в тип double.

Расширяющее преобразование типов Java можно изобразить еще так:

Сплошные линии обозначают преобразования, выполняемые без потери данных. Штриховые линии говорят о том, что при преобразовании может произойти потеря точности.

Стоит немного пояснить почему, к примеру тип byte не преобразуется автоматически (не явно) в тип char, хотя тип byte имеет ширину 8 бит, а char 16, тоже самое касается и преобразования типа short в char. Это происходит потому, что byte и short знаковые типы данных, а char без знаковый. Поэтому в данном случае требуется использовать явное приведение типов, поскольку компилятору надо явно указать что вы знаете чего хотите и как будет обрабатываться знаковый бит типов byte и short при преобразовании к типу char.

Поведение величины типа char в большинстве случаев совпадает с поведением величины целого типа, следовательно, значение типа char можно использовать везде, где требуются значения int или long. Однако напомним, что тип char не имеет знака, поэтому он ведет себя отлично от типа short, несмотря на то что диапазон обоих типов равен 16 бит.

short s = ( short ) 0xffff ; // Данные биты представляют число –1
char c = "\uffff" ; // Те же биты представляют символ юникода
int i1 = s ; // Преобразование типа short в int дает –1
int i2 = c ; // Преобразование char в int дает 65535

Сужающее преобразование (narrowing conversion ) происходит, если значение преобразуется в значение типа, диапазон которого не шире изначального. Сужающие преобразования не всегда безопасны: например, преобразование целого значения 13 в byte имеет смысл, а преобразование 13000 в byte неразумно, поскольку byte может хранить только числа от −128 до 127. Поскольку во время сужающего преобразования могут быть потеряны данные, Java компилятор возражает против любого такого преобразования, даже если преобразуемое значение укладывается в более узкий диапазон указанного типа:

int i = 13 ;
byte b = i ; // Компилятор не разрешит это выражение

Единственное исключение из правила – присвоение целого литерала (значения типа int) переменной byte или short, если литерал соответствует диапазону переменной.

Сужающее преобразование это всегда явное преобразование типов .

Явное преобразование примитивных типов

Оператором явного преобразования типов или точнее говоря приведения типов являются круглые скобки, внутри которых указан тип, к которому происходит преобразование – (type) . Например:

int i = 13 ;
byte b = ( byte ) i ; // Принудительное преобразование int в byte
i = ( int ) 13.456 ; // Принудительное преобразование литерала типа double в int 13

Приведение примитивных типов чаще всего используют для преобразования значений с плавающей точкой в целые числа . При этом дробная часть значения с плавающей точкой просто отбрасывается (то есть значение с плавающей точкой округляется по направлению к нулю, а не к ближайшему целому числу). По существу берется только целочисленная часть вещественного типа и она уже приводится к целевому типу целочисленного числа.

При приведении более емкого целого типа к менее емкому старшие биты просто отбрасываются . По существу это равнозначно операции деления по модулю приводимого значения на диапазон целевого типа (например для типа byte это 256).

Слишком большое дробное число при приведении к целому превращается в MAX_VALUE или MIN_VALUE .

Слишком большой double при приведении к float превращается в Float.POSITIVE_INFINITY или Float.NEGATIVE_INFINITY .

Таблица представленная ниже представляет собой сетку, где для каждого примитивного типа указаны типы, в которые их можно преобразовать, и способ преобразования. Буква N в таблице означает невозможность преобразования. Буква Y означает расширяющее преобразование, которое выполняется автоматически. Буква С означает сужающее преобразование, требующее явного приведения. Наконец, Y* означает автоматическое расширяющее преобразование, в процессе которого значение может потерять некоторые из наименее значимых разрядов. Это может произойти при преобразовании int или long во float или double. Типы с плавающей точкой имеют больший диапазон, чем целые типы, поэтому int или long можно представить посредством float или double. Однако типы с плавающей точкой являются приближенными числами и не всегда могут содержать так много значащих разрядов в мантиссе, как целые типы.

Автоматическое расширение типов в выражениях

Так же стоит еще раз упомянуть об автоматическом повышении (расширении) типов в выражениях. Мы с этим уже сталкивались когда рассматривали целочисленные типы данных и операции над ними, но все же стоит и тут напомнить, чтобы усвоилось еще лучше и к тому же это имеет непосредственное отношение к данной теме. В примере ниже знак @ + , , * , / и т.п.

То есть, все целочисленные литералы в выражениях, а так же типы byte , short и char расширяются до int . Если, как описано выше, в выражении не присутствуют другие, более большие типы данных (long , float или double ). Поэтому приведенный выше пример вызовет ошибку компиляции, так как переменная c имеет тип byte , а выражение b+1, в результате автоматического повышения имеет тип int .

Неявное приведение типов в выражениях совмещенного присваивания

Хоть данный раздел и относится к неявному преобразованию (приведению) типов, его объяснение мы привели тут, поскольку в данном случае так же работает и автоматическое расширение типов в выражениях, а затем уже неявное приведение типов. Вот такой кордебалет. Пример ниже я думаю все разъяснит. Так же как и в предыдущем объяснении знак @ означает любой допустимый оператор, например + , , * , / и т.п.

Это стоит пояснить на простом примере:

byte b2 = 50 ;
b2 = b2 * 2 ; // не скомпилируется
b2 *= 2 ; //скомпилируется, хотя и равнозначна b2 = b2 * 2

Вторя строка, приведенная в примере не скомпилируется из-за автоматического расширения типов в выражениях, так как выражение b2*2 имеет тип int, так как происходит автоматическое расширение типа (целочисленные литералы в выражении всегда int). Третья же строка спокойно скомпилируется, так как в ней сработает неявное приведение типов в совмещенном выражении присваивания.

Boxing/unboxing – преобразование примитивных типов в объекты обертки

Boxing и unboxin – это тоже достаточно большая тема, но она достаточно простая.

По существу boxing и unboxing это преобразование примитивных типов в объекты обертки и обратно .

Для объектов оберток примитивных типов применимо все что было сказано выше.

Об классах обертках упоминалось в таблицах, при разборе каждого из примитивных типов. Но тогда это было лишь упоминание в таблице.

Так вот, для каждого примитивного типа есть его старший брат, и он совсем не примитивный, а является настоящим классом, с полями и методами. И для каждой такой парочки возможно автоматическое преобразование.

Обычно, если в программе есть много математических вычислений, то лучше пользоваться примитивными типами, так как это быстрее и экономнее с точки зрения ресурсов, но иногда бывает необходимость преобразовать примитивный тип в объект.

Приведу простой пример:

int i3 ;
byte b2 = 3 ;
Byte myB ;
myB = b2 ;
myB ++;
b2 = myB ;
i3 = myB ;

Если пока не понятно зачем это нужно, то это не страшно, просто завяжите узелок на память.

Данная статья:

  • написана командой . Надеемся, что она Вам будет полезна. Приятного прочтения!
  • это одна из статей из нашего

Преобразование типов - это тема, которая может показаться сложной начинающим программировать на Java. Однако, заверим Вас, на самом деле всё просто. Главное понять по каким законам происходит взаимодействие между переменными и помнить об этом при написании программ . Итак, давайте разбираться.

В Java существует 2 типа преобразований - картинка Вам в помощь:

Напомним, что вся "Вселенная Java" состоит из:

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

В данной статье мы:

  • рассмотрим преобразование типов для примитивных типов переменных
  • преобразование объектов (String, Scanner и др.) в этой статье не рассматривается, поскольку с объектами происходит отдельная «магия» - это тема для отдельной статьи.
Автоматическое преобразование

Ну, что ж, давайте попробуем разобраться что такое "автоматическое преобразование".

Помните, когда мы рассматривали типы переменных (в статье ), мы говорили, что переменная - это некоторый «контейнер» , в котором может храниться значение для дальнейшего использования в программе. Также мы говорили о том, что каждый тип переменной имеет свой диапазон допустимых значений и объем занимаемой памяти. Вот она табличка, где это все было расписано:

Так вот, к чему мы, собственно говоря, клоним. К тому, что совсем не просто так Вам давались диапазоны допустимых значений и объем занимаемой памяти 🙂

Давайте, сравним, например:

1. byte и short. byte имеет меньший диапазон допустимых значений, чем short. То есть byte это как бы коробочка поменьше, а short - это коробочка побольше. И значит, мы можем byte вложить в short.

2. byte и int . byte имеет меньший диапазон допустимых значений, чем int. То есть byte это как бы коробочка поменьше, а int - это коробочка побольше. И значит, мы можем byte вложить в int.

3. int и long. int имеет меньший диапазон допустимых значений, чем long. То есть int это как бы коробочка поменьше, а long - это коробочка побольше. И значит, мы можем int вложить в long.

Это и есть пример автоматического преобразования. Это можно схематически изобразить в виде вот такой картинки:

Давайте рассмотрим как это работает на практике.

Пример №1

Код №1 - если Вы запустите это код на своем компьютере,

class Test { public static void main(String args) { byte a = 15; byte b = a; System.out.println(b); } }

class Test {

byte a = 15 ;

byte b = a ;

Код №2 - если Вы запустите это код на своем компьютере, в консоли будет выведено число 15

class Test { public static void main(String args) { byte a = 15; int b = a; System.out.println(b); } }

class Test {

public static void main (String args ) {

byte a = 15 ;

int b = a ;

System . out . println (b ) ;

И-и-и? Вы думаете, что раз в консоль было выведено одно и то же число, и код №1 отличается от кода №2 всего лишь типом переменной b, то между ними нет никакой разницы? Э то не так.

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

Хотя число, в принципе, одно и то же, но теперь оно находится в бо льшем контейнере, который занимает больше места на диске. При этом, JVM выполняет автоматические преобразования за Вас. Она знает, что int больше чем byte .

Приведение типов

Другое дело если вы пытаетесь переложить что-то из большего контейнера в более маленький.

Вы можете знать, что в большем контейнере лежит то, что поместиться и в маленьком – но об этом не знает JVM, и пытается предохранить вас от ошибок.

Поэтому, вы должны «прямо сказать», что ситуация под контролем:

class Test { public static void main(String args) { int a=0; long b=15; a = (int) b; } }

class Test {

public static void main (String args ) {

int a = 0 ;

long b = 15 ;

a = (int ) b ;

Тут мы дописали (int) перед b . Если бы переменная a была, к примеру, типа byte , в скобках бы стояло (byte) . Общая формула выглядит так:

Она говорит "сделай из (большего) значения b переменную нужного мне (целевого) типа int ".

Если что-то пошло не так.

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

Оказывается, в контейнере останется лишь то, что туда «влезло». К примеру, у чисел с плавающей точкой будет «отсекаться» дробная часть:

//пример 1 class Test { public static void main(String args) { double a=11.2345; int b=(int)a; System.out.println(b); // в консоли получится число 11 } }

//пример 1

class Test {

public static void main (String args ) {

double a = 11.2345 ;

int b = (int ) a ;

System . out . println (b ) ; // в консоли получится число 11

Надо помнить, что дробная часть не округляется , а отбрасывается .

А что будет, если мы попытаемся поместить число, которое выходит за допустимые границы? Например, если в byte (диапазон byte от -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 и Составьте таблицу такого вида:
byte short char int long float double boolean
byte
short
char
int
Long
Float
double
boolean

На пересечении напишите: а – если преобразование происходит автоматически, на – если нужно использовать явное преобразование, х – если преобразование невозможно.

* приведение типа к самому себе называется тождественным – его прописывать не обязательно

  1. Посмотрите еще раз, какой размер имеет каждый примитивный тип. Попытайтесь составить блок-схему, показывающую, куда помещаются какие типы. Проведите стрелочки с надписью «расширяющее преобразование» и «сужающее преобразование».
Вопросы

На собеседовании на должность Junior Java Developer Вас могут спросить:

Что Вы знаете о преобразовании примитивных типов данных, есть ли потеря данных, можно ли преобразовать логический тип?

Попробуйте ответить на вопрос.

Подытожим:
  • Если Вы "кладёте" в больший контейнер содержимое меньшего контейнера», преобразование происходит автоматически, и ошибок возникать не должно.
  • Если есть необходимость положить «значение из большего контейнера в меньший», нужно быть осторожным, и пользоваться явным приведением типов.
  • При приведении float или double к целочисленным типам, дробная часть не округляется, а просто отбрасывается.
  • Тип boolean не приводится ни к одному из типов.
  • Тип char приводится к числовым типам, как код символа в системе UNICODE.
  • Если число больше своего контейнера, результат будет непредсказуемым.

В этой статье описана только часть материала на тему приведения типов. Существуют также приведения объектных типов, приведение к строке (ведь в строке может быть записано все что угодно, правда?) и автоматическое продвижение типов в выражениях.

Надеемся, что наша статья была Вам полезна. Также есть возможность записаться на наши курсы по Java в Киеве. Обучаем с нуля. Детальную информацию Вы можете найти у нас на .


Часто возникает необходимость преобразования строк в значения других типов, таких как int или boolean, и наоборот. В соответствии с принятым соглашением ответственность за преобразование строки в значение другого типа возложена на соответствующий метод этого типа. Так, например, преобразование строки в величину типа int выполняет статический метод из состава класса-оболочки Integer. В следующей таблице указаны все типы, допускающие преобразование значений в строки и наоборот, и перечислены соответствующие методы.

ТИП Метод для преобразова- Метод для преобразования из строки

ния В строку

boolean String.valueOf(boolean) new.Boolean(String). booleanvalue()

byte 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)

Для преобразования строки в значение Boolean необходимо создать объект Boolean и затем запросить его значение. Все остальные классы-оболочки содержат Соответствующие методы parse. Методы parse целочисленных типов существуют в двух перегруженных формах: первая, помимо строки, требует задания дополнительного аргумента типа int, представляющего основание системы счисления – от 2 до 32; вторая принимает только параметр строки и по умолчанию предполагает использование десятичной системы счисления. Во всех случаях, кроме Boolean, предполагается следующее: если строка представляет значение, которое не может быть корректно преобразовано в число соответствующего типа, выбрасывается исключение NumberFormatException. Класс Boolean удовлетворяет соглашению, в соответствии с которым любая строка-параметр, не равная “true” (без учета регистра символов), приводит к созданию объекта вооlеаn со значением false.

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

Отсутствуют также и способы создания строковых представлений чисел, заданных в одном из поддерживаемых языком форматов – с ведущим нулем (О), обозначающим восьмеричное число, и префиксом Ох (или ОХ), служащим признаком шестнадцатеричной системы счисления. Напротив, в целочисленных классах-оболочках поддерживаются версии метода decode, способного преобразовать строки в числовые значения соответствующего типа и “понимающего”, что ведущий О обозначает восьмеричное число, а один из префиксов Ох ИЛИ Ох – шестнадцатеричное.

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

1. Что такое явное и автоматическое приведение типов в выражениях?

Приведение типов может быть явное и автоматическое.

При явном приведении типов сама операция приведения задается явным образом.

При автоматическом приведении типов нужно, чтобы выполнялись два условия:

  • оба типа должны быть совместимыми;
  • длина исходного типа (типа источника) должна быть меньше длины целевого типа (типа приемника).

2. Как выглядит явное приведение типов в выражениях? Примеры

Явное приведение типов позволяет осуществлять присвоение несовместимых типов. Общая форма явного приведения типов имеет вид:

(целевой_тип) значение

целевой_тип – это тип, в который нужно привести указанное значение .

Примеры явного приведения типов.

// явное приведение типов в выражениях byte b; int a; double d; float f; d = -39.9203; a = (int )d; // a = -39 f = (float )d; // f = -39.9203 b = (byte )d; // b = -39 d = 302930932; b = (byte )d; // b = -12 - урезание значения a = -27; b = (byte )a; // b = -27

3. Примеры автоматического приведения типов

Пример 1 . Автоматическое приведение целочисленных типов.

// автоматическое приведение целочисленных типов int a; byte b; short sh; b = -23; a = b; // a = -23 - автоматическое приведение типов sh = -150; a = sh; // a = -150 long l = 200; // Ошибка: "Type mismatch: cannot convert from long to int" // a = l; l = b; // l = -23 l = sh; // l = -150 char c = "Z" ; a = c; // a = 90 - код символа "Z" boolean b1 = false ; //a = b1; - ошибка, типы несовместимые

Пример 2 . Автоматическое приведение типов с плавающей запятой.

// автоматическое приведение типов с плавающей запятой float f; double d; f = 3.409033f; d = f; // d = 3.409033

Пример 3 . Автоматическое приведение смешанных типов. Такой случай возможен, если переменной типа с плавающей запятой присваивается значение переменной целочисленного типа.

// автоматическое приведение смешанных типов float f; double d; a = 28; d = a; // d = 28.0 f = a; // f = 28.0 // Ошибка: Type mismatch: cannot convert from float to int // a = f;

4. Как осуществляется автоматическое продвижение типов в выражениях?

Автоматическое продвижение типов происходит в выражениях. При этом, значение, которое фигурируют в выражениях, автоматически продвигаются к типам с большими диапазонами значений.

При автоматическом продвижении типов в выражениях:

  • если один из целочисленных операндов имеет тип int, то все значения типов byte, short и char продвигаются к типу int;
  • если один из целочисленных операндов имеет тип long, то все выражение продвигается к типу long;
  • если один из операндов относится к типу float, то тип всего выражения будет также типа float (если нет операндов типа double);
  • если один из операндов относится к типу double, то тип всего выражения будет также double.

5. Пример продвижения из типа byte в int в котором выражение не содержит операндов-переменных типа int (long)
// byte -> int byte b; b = 1000 / 20; // b = 50, работает, так как результат помещается в тип byte

Вышеприведенный пример работает корректно, так как:

  • результат помещается (совместим) в тип byte;
  • нет операндов типа int.

В вышеприведенном примере значения 1000 превышает диапазон значений типа byte. Сначала число 1000 приводится к типу int. Но результат

1000 / 20 = 50

приводится к типу byte и может корректно поместиться в переменной b .

Если написать так:

byte b; b = 100000 / 20; // ошибка, так как результат не помещается в тип byte

то выйдет ошибка компиляции с выводом сообщения:

В этом случае результат не помещается в тип byte:

100000 / 20 = 5000

Тогда это число (5000) автоматически становится типом int и компилятор выдаст сообщение об ошибке.

Если сделать явное приведение типов:

byte b; b = (byte ) (100000 / 20); // b = -120

то в этом случае результат 5000 типа int превращается в тип byte. Как известно, переменная типа int занимает 32 бита, а переменная типа byte занимает 8 бит. Значение переменной типа int урезается. И имеем то, что имеем (b = -120 ).

Вышеприведенные примеры относятся и к переменным типов short и char.

6. Пример. Продвижение из типа byte в тип int, в котором выражение содержит операнд-переменную типа int
// продвижение типов в выражениях // byte -> int byte b; int d; d = 20; // ошибка, результат есть типом int, так как переменная d есть типа int // b = 1000 / d;

В вышеприведенном примере в выражении используется переменная d типа int . Поэтому компилятор выдаст сообщение об ошибке:

Type mismatch: cannot convert from int to byte

Это означает, что результат есть типа int (а не byte ) даже если значение помещается в диапазон значений типа byte. Поскольку в выражении используется переменная-операнд d типа int.

Если осуществить явное приведение типов, то результат будет корректным:

// продвижение типов в выражениях // byte -> int byte b; int d; d = 20; b = (byte )(1000 / d); // b = 50 - работает корректно

7. Пример. Продвижение из типа int в тип long

Пример продвижения типов из int в long. Если один из операндов есть типа long, то все выражение продвигается к типу long.

int d; long l; d = 10000 * 200; // работает, d = 2000000 // Ошибка! Type mismatch: cannot convert from long to int // d = 1L * 2L; - операнды 1L и 2L есть типа long l = 100; // ошибка, один из операндов есть типа long // d = l * 2;

Как видно из примера, если один из операндов есть типа long , то все выражение становится типа long .



Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: