1. Список примитивных типов

В Java есть 8 базовых примитивных типов. Примитивными их называют потому, что значения этих типов не являются объектами и хранятся прямо внутри переменных.

Вот таблица, которая содержит краткую информацию по этим типам:

Тип Размер,
байт
Диапазон значений Значение по умолчанию Описание
byte 1 -128 .. 127 0 Самое маленькое целое — один байт
short 2 -32,768 .. 32,767 0 Короткое целое, два байта
int 4 -2*109 .. 2*109 0 Целое число, 4 байта
long 8 -9*1018 .. 9*1018 0L Длинное целое, 8 байт
float 4 -1038 .. 1038 0.0f Дробное, 4 байта
double 8 -10308 .. 10308 0.0d Дробное, двойной длины, 8 байт
boolean 1 true, false false Логический тип (только true & false)
char 2 0 .. 65,535 '\u0000' Символы, 2 байта, все больше 0
Значение по умолчанию

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

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

Но давайте вернемся к примитивным типам и рассмотрим их подробнее


undefined
8
Задача
Java Syntax Pro, 8 уровень, 1 лекция
Недоступна
Все возможные типы
Как тебе уже известно, всего в языке Java 8 примитивных типов. Создай по одной переменной каждого примитивного типа в классе Solution. Переменные не должны находиться в каком-либо методе.

2. Целые типы

В языке Java аж 4 целых типа: byte, short, int и long. Они отличаются размером и диапазоном значений, которые могут хранить.

Тип int

Самым часто используемым является тип int. Его название происходит от Integer (целый). Все целочисленные литералы в коде имеют тип int (если в конце числа не указана буква L, F или D).

Переменные этого типа могут принимать значение от -2,147,483,648 до +2,147,483,647.

Это достаточно много и хватает почти для всех случаев жизни. Почти все функции, которые возвращают число, возвращают число типа int.

Примеры:

Код Пояснение
int n = "Строка".length();
Метод length() возвращает длину строки
String[] array = {"Tic", "Tac", "Toe"};
int n = array.length;
Поле length содержит длину массива.

Тип short

Тип short получил свое название от short int. Его еще называют короткое целое. В отличие от типа int, его длина всего два байта и возможный диапазон значений от -32,768 до +32,767.

То есть в нем даже число миллион не сохранишь. Даже 50 тысяч. Это самый редко используемый целочисленный тип в Java. В основном его используют, когда хотят сэкономить на памяти.

Допустим, у вас ситуация, когда заранее известно, что значения с которыми вы работаете не превышает 30 тысяч, и таких значений миллионы.

Например, вы пишете приложение, которое обрабатывает картинки сверхвысокой четкости: на один цвет приходится 10 бит. А точек у вас в картинке — миллион. И вот тут уже играет роль, используете вы тип int или short.

Тип long

Этот тип получил свое название от long int — его еще называют длинное целое. В отличие от типа int, у него просто гигантский диапазон значений: от -9*1018 до +9*1018

Почему же он не является основным целым типом?

Все дело в том, что Java появилась еще в середине 90-х, когда большинство компьютеров были 32-х разрядными. А это значило, что все процессоры были заточены под работу с числами из 32-х бит. С целыми числами из 64-х бит процессоры работать уже умели, но операции с ними были медленнее.

Поэтому программисты разумно решили сделать стандартным целым типом тип int, ну а тип long использовать только тогда, когда без него действительно не обойтись.

Тип byte

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

Размер допустимых значений типа byte не так уж велик: от -128 до +127. Но не в этом его сила. Тип byte чаще всего используется, когда нужно хранить в памяти большой блок обезличенных данных. Массив типа byte просто идеально подходит для этих целей.

Например, вам нужно куда-то скопировать файл.

Вам не нужно обрабатывать содержимое файла: вы просто хотите создать область памяти (буфер), скопировать в нее содержимое файла, а затем записать эти данные из буфера в другой файл. Массив типа byte — то, что нужно для этих целей.

Тем более, что в переменной-типа-массив хранится только ссылка на область памяти. При передаче значения этой переменной в какой-то метод произойдет только передача адреса в памяти, а сам блок памяти копироваться не будет.

byte[] buffer = new byte[1024*1024];
FileInputStream sourceFile = new FileInputStream("c:\\data.txt");
FileOutputStream destFile = new FileOutputStream("c:\\output.txt");
while (true)
{
   int size = sourceFile.read(buffer);   // читаем данные из файла в буфер
   destFile.write(buffer, 0, size);      // записываем данные из буфера в файл

   // прекращаем копирование, если буфер заполнен не полностью
   if (size < buffer.length) break;
}
sourceFile.close();
destFile.close();

undefined
8
Задача
Java Syntax Pro, 8 уровень, 1 лекция
Недоступна
Максимальное целое
Создай по одной переменной каждого примитивного целочисленного типа в классе Solution. Этим переменным присвой максимально возможное для них значение. Никаких методов создавать не нужно.
undefined
8
Задача
Java Syntax Pro, 8 уровень, 1 лекция
Недоступна
Минимальное целое
Создай по одной переменной каждого примитивного целочисленного типа в классе Solution. Этим переменным присвой минимально возможное для них значение. Никаких методов создавать не нужно.

3. Вещественные типы

Среди примитивных типов также есть два вещественных. Хотя это не совсем точное название. Официально они называются числа с плавающей точкойfloating point numbers. Название происходит из стандарта, когда целую и дробную часть числа разделяет точка (а не запятая).

Полезно:

В каждой стране свои стандарты для записи чисел (внезапно!).

Многие из нас привыкли писать точки для разделения тысяч и запятую для отделения дробной части: например, миллион целых и 153 тысячных мы бы записали так 1.000.000,153. А вот в США, где жили создатели Java, принят другой стандарт: 1,000,000.153

В Java есть два примитивных типа с плавающей точкой: double и float.

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

Например, дробное число 987654.321 можно представить как 0.987654321*106. Поэтому в памяти оно будет представлено как два числа 987654321 (мантисса — значащая часть числа) и 6 (экспонента — степень десятки)

Тип float

Само название типа float происходит от floating point number. Размер этого типа совсем небольшой — всего 4 байта (32 бита), но он может хранить значения от -3.4*1038 до 3.4*1038. Под мантиссу отдается 24 бита, под экспоненту — 8 бит. Этот тип способен хранить всего 8 значащих цифр.

Такой подход позволяет хранить гораздо большие числа, чем int, используя все те же 4 байта. Но при этом мы жертвуем точностью. Часть памяти расходуется на хранение мантиссы, поэтому такие числа хранят всего 6-7 знаков после запятой, остальные отбрасываются.

Пример:

Код Значение переменной
float a = (float) 123.456789;
123.45679
float a = (float) 12345.9999;
12346.0
float a = (float) -123.456789E-2;
-1.2345679

Как видите, основной недостаток этого типа — очень маленькое количество значащих цифр и потеря точности уже в восьмой цифре. Поэтому тип float не сильно популярен среди Java-программистов.

Тип double

Тип double является стандартным типом с плавающей точкой. Его название происходит от double floating point. Его еще называют числом с плавающей точкой двойной точности. Все вещественные литералы по умолчанию имеют тип double.

Этот тип занимает 8 байт памяти (64 бита) и может хранить значения от -1.7*10308 до 1.7*10308. Важным моментом является то, что под его мантиссу отводится 53 бита, а остальные 11 – под экспоненту.

Это позволяет хранить 15-17 значащих цифр.

Пример:

Код Значение переменной
double a = 1234567890.1234567890;
1234567890.1234567
double a = 1234567890.1234512345;
1234567890.1234512
double a = 1234567890.1357913579;
1234567890.1357913

Такая точность, особенно в сравнении с типом float, является определяющей: 99% всех операций с вещественными числами выполняются с типом double.

Под экспоненту выделяется 11 бит, что позволяет хранить степень десятки от -323 до +308 (степень двойки — от -1024 до +1023). Тип double легко может хранить число с сотней нулей после запятой:

Код Значение переменной
double a = 2E-300 * 3E+302
600.0

undefined
8
Задача
Java Syntax Pro, 8 уровень, 1 лекция
Недоступна
Экспонентная запись числа
Перед тобой 5 общеизвестных величин. Перепиши их в более читаемый формат — экспоненциальный. Мантисса должна представлять собой дробное число от 1.0 до 10. После изменения формата чисел реальное значение, хранимое в переменной, не должно измениться. Пример: 109.1678 — обычная форма; 1.091678E+2 — экс

4. Бесконечность

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

Примеры:

Код Примечание
System.out.println( 100.0 / 0.0 );
Infinity
System.out.println( -100.0 / 0.0 );
-Infinity
double a = 1d / 0d;
double b = a * 10;
double c = b - 100;
a == Infinity
b == Infinity
c == Infinity

Если бесконечность умножить на число, получится бесконечность. Если к бесконечности добавить число, получится бесконечность. Очень удобно.

Не число (NaN)

Любые операции с бесконечностью дают бесконечность. В целом да, но не все.

Числа с плавающей точкой могут хранить еще одно специальное значение — NaN. Это сокращение от Not a Number (не число).

В математике, если разделить бесконечность на бесконечность, должна возникнуть неопределенность.

Ну, а в Java, если разделить бесконечность на бесконечность, будет NaN.

Примеры:

Код Примечание
System.out.println(0.0 / 0.0);
NaN
double infinity = 1d / 0d;
System.out.println(infinity / infinity);

NaN
double a = 0.0 / 0.0;
double b = a * 10;
double c = b - 100;
double d = a + infinity;
a == NaN
b == NaN
c == NaN
d == NaN

Любая операция с NaN дает NaN.


undefined
8
Задача
Java Syntax Pro, 8 уровень, 1 лекция
Недоступна
Бесконечность не предел
В методе main вызови метод div() 2 раза. Первый раз — с такими аргументами, чтобы вывод в консоли был "Infinity", а второй — "-Infinity". Код метода div() изменять нельзя.
undefined
8
Задача
Java Syntax Pro, 8 уровень, 1 лекция
Недоступна
Странное деление
В методе main вызови метод div() с таким аргументом, чтобы вывод в консоли был "NaN". Код метода div() изменять нельзя.

5. Тип char

Среди примитивных типов в Java есть еще один, который заслуживает особого внимания — тип char. Его название происходит от слова Character, а сам тип используется для того, чтобы хранить символы.

А ведь символы — это как раз то, из чего состоят строки: каждая строка содержит в себе массив символов.

Но еще интереснее тот факт, что тип char — это и числовой тип тоже! Так сказать, тип двойного назначения.

Все дело в том, что на самом деле тип char хранит не символы, а коды символов из кодировки Unicode. Каждому символу соответствует число — числовой код символа.

Каждая переменная типа char занимает в памяти два байта (как и тип short). Но в отличие от типа short, целочисленный тип char — беззнаковый, и может хранить значения от 0 до 65,535.

Тип char — гибридный тип. Его значения можно интерпретировать и как числа (их можно складывать и умножать), и как символы. Так было сделано потому, что хоть символы и имеют визуальное представление, для компьютера они в первую очередь просто числа. И работать с ними как с числами гораздо удобнее.

Unicode

Unicode — это специальная таблица (кодировка), которая содержит все символы мира. И у каждого символа есть свой номер. Выглядит она примерно так:

Примитивные типы в Java

Присвоить значение переменной типа char можно разными способами.

Код Описание
char a = 'A';
Переменная а будет содержать латинскую букву А.
char a = 65;
Переменная а будет содержать латинскую букву А. Ее код как раз 65.
char a = 0x41;
Переменная а будет содержать латинскую букву А.
Ее код как раз 65, что равно 41 в шестнадцатеричной системе.
char a = 0x0041;
Переменная а будет содержать латинскую букву А.
Ее код как раз 65, что равно 41 в шестнадцатеричной системе.
Два лишних нуля ничего не меняют.
char a = '\u0041';
Переменная а будет содержать латинскую букву А.
Еще один способ задать символ по его коду.

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

И как мы говорили, тип char — это и целочисленный тип тоже, поэтому можно написать так:

Код Вывод на экран
char a = 'A';
a++;
System.out.println(a);
На экран будет выведена латинская буква B.
Потому что:
A65
B66
C67

Работа с типом char

Каждый символ char — это в первую очередь число (код символа), а потом уже символ. Зная код символа, всегда можно получить его в программе. Пример:

Код Вывод на экран
char c = (char) 1128;
System.out.println(c);

Ѩ

Стандартные коды

Вот самые известные коды символов:

Символы Коды
0, 1, 2, ... 9 48, 49, 50, ... 57
a, b, c, ... z 97, 98, 99, ... 122
A, B, C, ... Z 65, 66, 67, ... 90

undefined
8
Задача
Java Syntax Pro, 8 уровень, 1 лекция
Недоступна
5 оттенков char
В методе main() измени порядок вызова методов System.out.print() таким образом, чтобы вывод на консоль был: "Hello char". Значение переменных не изменяй. В методе main() никакого кода больше не дописывай.

6. Тип boolean

И последний примитивный тип — это boolean.

Как вы уже знаете, он может принимать только два значения: true и false.

Собственно, все, что можно знать об этом типе, вы уже знаете.