суббота, 15 декабря 2018 г.

4 Типы данных в JAVA

   Тип данных определяет:
 
      - множество (диапазон) значений, которые могут принимать величины этого типа (которые может хранить переменная или константа)
      - операции, которые могут выполняться над величинами этого типа
      - внутреннее представление данных в памяти компьютера


   Размер типов данных остается неизменным на всех платформах (стандартизирован).
 
   Java - строго типизированный (не динамический) язык программирования. Это означает, что тип данных каждой переменной и выражений задается заранее и известен при компилировании.
 

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

    Примитивные типы Java  – это типы, для которых в ячейке памяти содержатся основные значения (непосредственно данные) – скалярные величины (простые битовые структуры), которые не являются объектами и имеют значения по умолчанию. 
 
   При выполнении операции присваивания для переменных, имеющих примитивный тип, выполняется копирование данных из одной ячейки памяти в другую.
   Примитивными являются логический тип boolean, целые числовые типы byte, short, int, long, char и плавающие числовые типы float и double.
 
 
 
Непримитивные (сложные) типы Java

   Сложные (непримитивные типы данных) образуются из простых путём группировки.
   Переменные примитивных типов хранят в себе значения, а переменные типов-классов хранят ссылку на объекты этого же класса, или null (если ссылка не задана). 
   Например,  String (Строка) - сложный, непримитивный тип данных, хранящий свои данные в виде таблицы символов, где каждый символ таблицы - это примитивный тип char.

    Чтобы большие (сложные) типы, содержащие в себе много маленьких (примитивных) не занимали много памяти и присваивание таких переменных выполнялось наиболее быстро, переменные сложных типов хранят в себе не сам объект, а всего лишь ссылку на него - четырёхбайтовый адрес (этого хватает, чтобы можно было обращаться к данным этих объектов). Такой механизм поддерживается Java-машиной.


Рис. 1 Схема классификации типов данных

   Классы в Java представляют собой сложные составные типы данных, данные которого будут либо другими сложными (непримитивными) типами данных и/или примитивными.
 
 
 
Примитивные типы данных

   Среди примитивных типов данных выделяют четыре типа для целочисленных значений (byte, short, int и long), два типа для дробных данных с плавающей точкой (float и double), один тип данных для символов (char) и один тип данных для логических условий true и false (boolean).
 
   В таблице ниже приведены все примитивные типы данных и их характеристики:
   Здесь Size - разрядность (количество байтов, выделяемых для хранения значений типа в оперативной памяти)
      Example Literals - диапазон значений.

   Если требуется создать ссылку на один из примитивных типов данных, необходимо использовать соответствующий класс-обертку. Оборачивание примитива в объект называется упаковкой (boxing), а обратный процесс распаковкой (unboxing).
 
   Соответствие типов данных классам-оберткам:
      byte соответсвует Byte
      short Short
      int Integer
      long Long
      char Character
      float Float
      double Double 
      boolean Boolean


Целочисленные типы данных
 
    • byte: 
         хранит целое число
         диапазон значений: от -128 до 127
         занимает 1 байт
         значение по умолчанию 0

    • short
         хранит целое число
         диапазон значений: от -32768 до 32767
         занимает 2 байта
         значение по умолчанию 0

    • int
         хранит целое число
         диапазон значений: от -2147483648 до 2147483647
         занимает 4 байта
         значение по умолчанию 0

    • long
         хранит целое число
         диапазон значений: от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807
         занимает 8 байт
         значение по умолчанию 0L (используйте заглавную букву, что бы не спутать букву с единицей)
   (По умолчанию, java интерпретирует все целочисленные переменные как 32-битные значения типа integer. Если нужноуказать, что используется тип long, нужно добавлять суффикс L в конце значения.

   Помимо десятичной системы счисления, можно применять и другие. К примеру:

   int u = 0x6F; // 16-иричная система, число 111
    (Для задания шестнадцатеричного значения после символов 0x указывается число в шестнадцатеричном формате)

   int u = 010; // 8-иричная система, число 8
    (Для задания восьмеричного значения после символа 0 указывается число в восьмеричном формате)

   int u13 = 0b1101; // 2-иричная система, число 13 .
    (Для задания двоичного значения после символов 0b указывается число в двоичном формате)


   Также целые числа поддерживают разделение разрядов числа с помощью знака подчеркивания:
   int x = 123_456; int y = 234_567__789;
   System.out.println(x); // 123456 System.out.println(y); // 234567789

   При делении целочисленных данных остаток отбрасывается.
 


Тип данных с плавающей точкой

    Вещественные числа могут быть представлены в двух форматах:
      - с фиксированной точкой – совпадает с обычной математической записью десятичного числа с дробной частью, в качестве разделителя целой и дробной части в дробных литералах используется точка.
      - с плавающей точкой – применяется при записи очень больших или очень малых чисел. В этом формате число, стоящее перед символом «E», умножается на число 10 в степени, указанной после символа «E».
 
   Значения вещественных типов в компьютере представляются приближенно и определяются двумя типами:

   • double
         хранит число с плавающей точкой
         диапазон значений: от ±4.9*10^-324 до ±1.8*10^308
         занимает 8 байт
         значение по умолчанию 0.0D (с двойной точностью - 17 цифр)
   • float
         хранит число с плавающей точкой
         диапазон значений: от -3.4*10^38 до 3.4*10^38
         занимает 4 байта; Значение по умолчанию 0.0F (с одинарной точностью - 7-8 цифр)

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

   При присвоении переменной типа float дробного литерала с плавающей точкой, например, 3.1, 4.5 и т.д., Java автоматически рассматривает этот литерал как значение типа double.
   Чтобы указать, что данное значение должно рассматриваться как float, нам надо использовать суффикс f: float fl = 30.6f; double db = 30.6;
   В данном случае обе переменных имеют практически одно значение, но эти значения будут по-разному рассматриваться и будут занимать разное место в памяти.

    К обычным вещественным числам добавляются еще три значения:
      - положительная бесконечность, выражаемая константой POSITIVE_INFINITY и возникающая при переполнении положительного значения
      - отрицательная бесконечность, выражаемая константой NEGATIVE_INFINITY и возникающая при переполнении отрицательного значения
      - «не число», выражаемое константой NaN (Not a Number) и возникающее при делении вещественного числа на нуль или умножении нуля на бесконечность.
 
   Кроме того, спецификация языка Java различает положительный и отрицательный нули (+0.0 и -0.0), возникающие при делении на бесконечность соответствующего знака.


Логический тип данных boolean

   • boolean: хранит значение 'true' или 'false'; Значение по умолчанию 'false'.

    boolean isActive = false;
    boolean isAlive = true;
 
    char sex='m';
    boolean isSexM = 'm' == 1;  //В результате isSexM = true;
 
    Типы boolean и integer в языке Java несовместимы между собой.
    В отличие от языков C и C++, в Java константа true не равна 1, а константа false не равна 0.
 

Тип текстовых данных

   • char: 
      хранит одиночный символ в кодировке UTF-16 (символ представлен в 16-битным значением в Unicode-таблице) и поэтому занимает 2 байта
      диапазон его хранимых значений от 0 до 65535, что позволяет использовать 65536 различных символов
      значение по умолчанию ‘\ u0000’

    Unicode – это стандарт кодирования символов, который позволяет предоставить знаки всех языков мира. Поскольку Java использует набор символов UNICODE он поддерживает интернационализацию.

   В качестве значения переменная символьного типа получает одиночный символ, заключенный в ординарные кавычки:
char ch='e';
   Кроме того, переменной символьного типа также можно присвоить целочисленное значение от 0 до 65536. В этом случае переменная опять же будет хранить символ, а целочисленное значение будет указывать на номер символа в таблице символов Unicode (UTF-16).
   Еще одной формой задания символьных переменных является шестнадцатеричная форма: переменная получает значение в шестнадцатеричной форме, которое следует после символов '\u'. 
(Код любого символа в кодировке Unicode набирается в апострофах после обратной наклонной черты и латинской буквы u четырьмя шестнадцатеричными цифрами.) 
   Таким образом, можно закодировать все символы Unicode последовательностями от \u0000 до \uFFFF.  

   Например, если в программу нужно вставить знак с кодом 6917, необходимо его представить в шестнадцатеричном формате (1B05) и записать это значение как \u1B05, причем буква u должна быть строчной, а шестнадцатеричные цифры A, B, C, D, E, F можно использовать как заглавные, так и строчные. 

   Пример: char ch='\u0066'; будет хранить символ 'f'.


   Символьные переменные не стоит путать со строковыми: здесь 'a' не идентично "a".

   Строковые переменные представляют объект String, который в отличие от char или int не является примитивным типом в Java: String hello = "Hello..."; System.out.println(hello);

    Тип char является псевдоцелочисленным типом, поэтому значения этого типа можно задавать в виде числа - кода символа из таблицы кодировки UTF-16. Каждому символу соответствует определённое число из таблицы и Java при виде этого числа в рамках типа char выводит его на экран как символ. То есть, например, при выполнении кода
   char c2 = 97;
   System.out.println(c2);
 
   на консоль выведется a.


Ссылочные типы данных
 
   Ссылочными типами называются типы данных, для которых в ячейке памяти содержится не сами данные, а только адреса этих данных, то есть ссылки на данные.
   К ссылочным типам относятся классы, интерфейсы и массивы.
   Существует также специальный нулевой тип – это зарезервированное слово null, обозначающее нулевой адрес.
 
   Свойства ссылочного типа данных:
      - при выполнении операции присваивания в ссылочную переменную заносится адрес данных, а не сами данные
      - непосредственный доступ к адресу, хранящемуся в ссылочных переменных, в языке Java отсутствует
      - ссылки можно присваивать друг другу, только если они совместимы по типам
      - если переменной ссылочного типа не присвоено значение (ещё нет ссылки на какой-то объект), в ней хранится значение null – специальная «пустая ссылка».
   В этом случае переменная просто хранит адрес объекта равный 0, но так как Java-машина никогда не создаёт объекты с таким адресом, распознает, что если переменная-ссылка содержит 0, то никакого объекта там нет.

      - ссылочным переменным можно присваивать значение null (пустую (нулевую) ссылку):
         b=null;
 
 
   Приведение примитивных типов данных
   (преобразование выражения одного типа данных к выражению другого типа данных)

   Рис.2 Схема совместимости типов данных 

   Здесь: сплошные линии указывают на преобразования без потери данных - с расширением, штриховые линии - на операции с возможной потерей данных, сужающие.
 
 
   Случай 1) Преобразование с расширением (conversion):
      переменная меньшей ёмкости назначается другой переменной большей ёмкости. (автоматическое преобразование)
   Например, от типа byte  к типу int.

   В данном случае конфликта не происходит (такие преобразования безопасны) и операции выполняются автоматически, без дополнительных указаний: новый тип всегда гарантированно вмещает в себя все данные, которые хранились в старом типе, и таким образом не происходит потери данных.
   Поэтому компилятор осуществляет это преобразование сам и никакихспециальных действий для этого предпринимать не требуется.
   Расширяющими являются следующие преобразования:
      - от byte к short, int, long, float, double
      - от short к int, long, float, double
      - от char к int, long, float, double
      - от int к long, float, double
      - от long к float, double
      - от float к double


   Случай 2) Преобразование сужающее (type casting):
      переменная большей ёмкости назначается другой переменной меньшей ёмкости. (явное преобразование типов)

   В данном случае может произойти конфликт и данные могут быть потеряны.
   В Java такое преобразование должно совершаться явным образом, т.е.программист в коде должен явно указать, что он намеревается осуществить такое преобразование и готов идти на потерю данных.
   Операция явного преобразования типов предполагает указание перед переменной или выражением в скобках того типа, к которому надо преобразовать значение. Например, если написать(byte) перед значением типа int, мы в качестве результата получим значение типа byte

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

  Для дробных типов (float и double) сужение (приведение такого числа к целочисленному типу) происходит с отбрасыванием у него дробной части.

   При выполнении операций с переменными, имеющими различные типы данных, тип каждого операнда и результата автоматически повышается до типа с наибольшей ёмкостью; при этом тип данных переменной, которой присваивается результирующее значение должен соответствовать ёмкости результата или же должно использоваться явное приведение.
 
   Пример потери данных при сужающем пребразовании:
   Изначальное значение, хранящееся в переменной типа int - 10000000. Она занимает 32 бита памяти.
   При записи этого значения в переменную типа short, которая может хранить только 16 бит, происходит следующее: только первые 16 бит вышеуказанного числа будут туда перемещены, остальные - отбросятся, не производится округления или каких-либо других действий для получения более корректного результата.
 
Примечания:
! Если сложить число и строку, то Java автоматически конвертирует число в строку.

 
Объявление и инициализация переменных

   Чтобы объявить переменную, для неё необходимо указать тип данных и присвоить ей уникальное имя.

   Пример объявления типа данных:
 int a;

    Также можно комбинировать объявление переменных и их инициализацию:
char b='m';
 
   Пример операции с ссылочными (сложными) переменными:

ТипПеременной имяПеременной = ссылка на новосозданный объект вида (( new ТипСоздаваемогоОбъекта(); ))

 Okras okras=new Okras();

*использованы материалы с сайтов:
https://guru99.ru/java-variables/
https://www.geeksforgeeks.org/data-types-in-java/
https://java-master.com/primitive-types-of-data-in-java/
https://javarush.ru/groups/posts/630-primitivnihe-tipih-v-java--ne-takie-uzh-oni-i-primitivnihe

Комментариев нет:

Отправить комментарий

Наследование в Java

   «родительское/дочернее»     Наследование (inheritance) - свойство системы, позволяющее описать (создать) новый класс на основе уже су...