Какие существуют примитивные типы данных в java?
Содержание:
- Ограниченные типы
- Автобокс
- Абстрактный класс и интерфейс
- 2.2 Типы с плавающей точкой (Floating-point Types)
- ⇑
- 7. Пример описания и использования переменных с плавающей запятой.
- 8. Какие особенности применения символьного типа данных char?
- 9. Примеры описания и использования переменных типа char
- 10. Какое назначение в программах имеет тип boolean?
- 11. Какие отличия между примитивными типами и типами-ссылками?
- 12. Существуют ли беззнаковые примитивные типы?
- Литералы строк
- Параметры класса
- Явное
- Литералы вещественных чисел
- Типы данных в Java
- Класс Character
- Присваивание целых и вещественных чисел
- Интерфейс
- Clone
- Методы
- Методы класса
- Основы класса Integer
- Литералы символов
- Загрузка статического и динамического класса
- Конструкторы
Ограниченные типы
Указывая параметр типа, можно наложить ограничение сверху в виде верхней границы, где объявляется супер класс, от которого должны быть унаследованы все аргументы типов. С этой целью вместе с параметром указывается ключевое слово :
Параметр типа может быть заменен только указанным супер классом или его подклассами.
Рассмотрим пример использования ограниченного типа:
В виде ограничения можно накладывать не только тип класса, но и тип интерфейса:
Ограничение может включать в себя как тип класса, так и типы одного или нескольких интерфейсов:
Тип класса должен быть задан первым. Накладывая на обобщенный тип ограничение, состоящее из класса и одного или нескольких интерфейсов, для их объединения следует воспользоваться логической операцией &: Таким образом, любой тип, передаваемый параметру , должен быть подклассом, производным от класса и реализующим интерфейсы и .
Автобокс
До Java 5 вам приходилось вызывать методы для объектных примитивных типов, чтобы получить их значение:
Integer myInteger = new Integer(45); int myInt = myInteger.intValue();
С Java 5 у вас есть понятие, называемое «автобокс». Это означает, что оболочка может автоматически «упаковывать» примитивную переменную в объектную версию или «распаковывать» объектный примитив. В зависимости от того, что требуется. Предыдущий пример может быть написан так:
Integer myInteger = new Integer(45); int myInt = myInteger;
В этом случае Java автоматически извлечет int из myInteger и присвоит это значение myInt.
Точно так же создание объектной примитивной переменной было ручным действием:
int myInt = 45; Integer myInteger = new Integer(myInt);
С помощью автобокса оболочка может сделать это за вас. Теперь запись выглядит так:
int myInt = 45; Integer myInteger = myInt;
Затем Java автоматически «упаковывает» примитив в объектную версию соответствующего типа.
Функции автобокса позволяют использовать примитивы, для которых обычно требовалась его объектная версия и наоборот. Есть одна ловушка. Переменная object (ссылка) может указывать на ноль, то есть на ничто. Если попытаетесь преобразовать ноль в примитивное значение, получите исключение NullPointerException (ошибка, которая приводит к сбою программы). Этот код показывает пример этого:
Integer myInteger = null; int myInt = myInteger;
Этот код будет хорошо скомпилирован, но при выполнении он приведет к исключению NullPointerException, поскольку myInteger указывает на ноль. Таким образом, невозможно преобразовать (распаковать) значение объекта, на который он указывает, поскольку не указывает ни на один объект.
Абстрактный класс и интерфейс
- В интерфейсе отсутствует код реализации, а все методы являются абстрактными. То есть, все методы объявляются, но ни один не определяется.
- В абстрактном классе есть исполняемые и абстрактные методы.
- Класс реализует сколько угодно интерфейсов, но расширяет только один абстрактный класс.
- Методы абстрактного класса могут быть или не быть абстрактными.
- Абстрактный класс не может превратиться в экземпляр, но может стать подклассом.
- Все абстрактные методы должны определяться в подклассе, то есть, подкласс является абстрактным.
- Создавать экземпляры из интерфейса нельзя. Их можно реализовывать в других классах или расширять другими интерфейсами.
- Переменные интерфейсов конечные и статические. По умолчанию, все методы интерфейса публичные и абстрактные.
- Интерфейс не может содержать реализацию и не может превращаться в подкласс. Все переменные должны быть постоянными.
2.2 Типы с плавающей точкой (Floating-point Types)
Литералы с плавающей точкой могут быть записаны в научной нотации с помощью символа E (или e) означающего в данном контексте экспоненту. Например, double-литерал 194.9E-2 в научной нотации интерпретируется как 194.9 × 10-2 (т.е. 1.949).
Десятичная точка и экспонента для чисел с плавающей являются опциональными и указываются при необходимости. Однако как минимум одна цифра должна быть указана.
2.2.1 float
Для литерала с плавающей точкой может быть указан тип float для этого нужно добавить к значению суффикс F (или f).
Примеры float-литералов |
Для float-литералов суффикс F является обязательным, иначе они будут считаться double-литералами.
⇑
7. Пример описания и использования переменных с плавающей запятой.
float f; // переменная с именем f типа float f = 3.998f; // переменной f присвоить значение 3.998 double d; // переменная с именем d типа double d = -340.349489287; float ff = -3.99f; // инициализация переменной ff типа float double dd = 779303028.3398; // инициализация переменной dd типа double
8. Какие особенности применения символьного типа данных char?
В Java для представления символов введен тип данных char.
Переменные типа char занимают в памяти компьютера 16 бит. Это связано с тем, что для представления символов char в Java используется кодировка Юникод (Unicode). Диапазон допустимых значений этого типа составляет от до 65535.
Использование кодировки Unicode связано с тем, что программы на Java используются во всем мире, то есть в странах, где для представления символа нужно 2 байта (16 бит). Такими странами есть, например, Япония, Китай.
9. Примеры описания и использования переменных типа char
char c; // переменная с именем c типа char c = 'Z'; // присвоение литерала 'Z' c = 90; // c = 'Z' c--; // c = 'Y' char cc = '2'; // инициализация переменной cc значением '2'
10. Какое назначение в программах имеет тип boolean?
Тип boolean предназначен для сохранения логических значений. Переменные типа boolean могут принимать только два значения: true или false.
Пример использования переменных типа boolean.
boolean b; b = true; boolean bb=false; // bb = false bb = 5>4; // bb = true bb = 55==6; // bb = false
11. Какие отличия между примитивными типами и типами-ссылками?
Между примитивными типами и типами-ссылками существуют следующие отличия:
- переменная примитивного типа не является переменной-ссылкой (объектом);
- переменная примитивного типа есть «автоматической» и сохраняется в стеке. Объект (переменная) сохраняется в «куче». Поэтому производительность работы с переменными примитивного типа выше;
- при объявлении переменной примитивного типа не нужно выделять память оператором new;
- переменная примитивного типа напрямую сохраняет свое значение в отличие от переменной-ссылки.
12. Существуют ли беззнаковые примитивные типы?
Нет. В языке Java все примитивные типы являются знаковыми, то есть, могут принимать отрицательные значения.
- Литералы. Идентификаторы. Ключевые слова. Комментарии
- Переменные. Объявление переменных. Инициализация переменных
- Преобразование и приведение типов. Автоматическое продвижение типов в выражениях
Литералы строк
В коде также можно задавать и целые строки текста. Чтобы компилятор считал строку именно данными (строкой текста), а не частью кода, вся строка с двух сторон обрамляется двойными кавычками.
Если в одной строке кода много двойных кавычек, они разбиваются на пары. Первая двойная кавычка обозначает начало литерала, следующая за ней — конец литерала. Следующая за ней — опять начало нового литерала, следующая за ней — конец второго литерала. И т.д.
Каждый такой литерал имеет тип .
Примеры
Код | Пояснение |
---|---|
В строке 5 литералов, каждый из которых состоит из одного символа | |
Литерал пустая строка. Строка, в которой нет символов. | |
Тут два литерала. Результатом будет строка , но не число | |
Тут тоже два литерала. Оператора return тут нет. |
Если строковый литерал слишком длинный, его можно разбить на несколько строк и склеить «оператором плюс»:
Код | Пояснение |
---|---|
Если вывести эту строку на экран, весь текст выведется в одну строку! |
Параметры класса
Мы можем создавать поля класса, каждое из которых имеет свой тип.
Поле класса — это переменная, которая описывает какое-либо из свойств данного класса.
Для наших домашних питомцев и полями класса будут вес, кличка и принадлежность к определённому типу (коровы, гуси, собаки и так далее). Очевидно, что здесь вес — это числовая переменная, а кличка и тип — строки символов. Тогда мы можем написать:
Переменные weight, name и type — поля нашего класса Pet, то есть свойства, которые описывают объект этого класса. Таких полей может быть сколько угодно, каждое имеет свой тип, как обычная переменная.
Мы уже пару раз упомянули словосочетание «объект класса». Так говорят, потому что любой объект является экземпляром какого-либо класса. Здесь действует простая аналогия: класс — это как бы чертёж, который описывает объект, его устройство, а объект — реализация чертежа, его материальное воплощение.
Давайте запрограммируем первый объект класса Pet. Пусть это будет кот (type) с кличкой (name) Барсик и весом (weight) 10 (измерение в килограммах).
Сперва необходимо создать переменную типа Pet:
Наш объект pet выглядит как обычная переменная, но в качестве типа указан класс Pet, и в данный момент в нём ничего нет. Инициализируем объект — воспользуемся такой синтаксической конструкцией:
Мы ставим знак равно, пишем ключевое слово new, имя нашего класса и круглые скобки. Принято говорить, что здесь мы вызываем конструктор класса Pet. Пока просто запомним это — о конструкторах и о том, как их использовать, будет рассказано в отдельной статье.
Теперь у нас появилась переменная pet типа Pet, в которой содержится объект класса Pet. Ранее в этом классе мы объявили поля, к которым можно обратиться и занести в них значения.
Чтобы получить доступ к какому-либо полю нашего класса Pet, нужно специальным образом обратиться к переменной pet — поставить точку и вызвать необходимое поле. Например, вот так:
Теперь во всех трёх полях есть по значению, а мы можем получить их из программы, если потребуется, — например, распечатать в консоль:
Изменить значение в любом из полей класса также несложно. Пусть наш кот Барсик слегка потолстеет — добавим к его весу 1 кг:
Как видим, мы просто изменили вес в поле weight, а при выводе получили уже другое значение.
Явное
В этом случае, если вы хотите присвоить значение большего типа данных меньшему типу данных, вы можете выполнить явное приведение или сужение типов. Это полезно для несовместимых типов данных, где автоматическое преобразование невозможно.
Давайте разберемся с этим на примере.
//Java program to illustrate explicit type conversion public class Narrowing { public static void main(String[] args) { double d = 200.06; //explicit type casting long l = (long)d; //explicit type casting int i = (int)l; System.out.println("Double Data type value "+d); //fractional part lost System.out.println("Long Data type value "+l); //fractional part lost System.out.println("Int Data type value "+i); } }
Вывод:
Double Data type value 200.06 Long Data type value 200 Int Data type value 200
Явное приведение в выражениях
Когда вы вычисляете выражения, выходные данные автоматически обновляются до большего типа данных операнда. Но если вы сохраните этот результат в каком-либо меньшем типе данных, он генерирует ошибку времени компиляции, из-за которой нам нужно набрать приведение вывода.
Пример:
//Java program to illustrate type casting int to byte public class ExplicitTest { public static void main(String args[]) { byte b = 70; //type casting int to byte b = (byte)(b * 2); System.out.println(b); } }
Вывод:
Литералы вещественных чисел
В коде можно задавать не только целочисленные, но и литералы с плавающей точкой (вещественные числа).
Собственно, правило очень простое: если в коде есть число и в его записи есть точка, это число — литерал с плавающей точкой. И не просто литерал, а литерал с типом .
Можно создать и литерал типа float, но для этого к числу в конце нужно приписать букву F (или f).
Примеры:
Код | Описание |
---|---|
Скомпилируется отлично. | |
Скомпилируется отлично. | |
Скомпилируется отлично. | |
Скомпилируется отлично. | |
Будет ошибка компиляции: переменная типа float, литерал типа double. |
Кстати, можно явно превратить целочисленный литерал в литерал типа float или double, просто приписав к нему суффикс F (для ) или D (для ). Примеры:
Код | Описание |
---|---|
Скомпилируется отлично. | |
Скомпилируется отлично. | |
Будет ошибка компиляции: переменная типа int, литерал типа . |
У литералов с плавающей точкой есть «научная форма записи»: кроме знаковой части числа можно еще указать и степень десятки этого числа. Пример:
Литерал | Математическая запись | Итоговое значение |
---|---|---|
Типы данных в Java
- Примитивы. (byte, short, char, int, float, long, double, boolean).
- Объекты. Размер объекта зависит от конкретной реализации VM и архитектуры процессора. Поэтому дать однозначный ответ не получится. Все же хочется понять (на примере конкретной VM) какой размер памяти выделяется под java-объект.
- Массивы. Одномерные линейные структуры, которые могут содержать все перечисленные типы (включая другие массивы). Массивы также являются объектами, но со специфичной структурой.
Примитивы
С размером примитивов все понятно — их размер определен в спецификации языка () и спецификации jvm (). Интересно заметить, что для типа boolean jvm использует int, а не byte как могло бы показаться (). Также интересно, что при создании массива boolean[] под каждый элемент массива будет выделен 1 байт, а не 4.
тип | размер (байт) | размер в массиве (байт) | допустимые значения |
---|---|---|---|
byte | 1 | 1 | -128 .. 127 |
short | 2 | 2 | -32768 .. 32767 |
chart | 2 | 2 | ‘\u0000’ .. ‘\uffff’ |
int | 4 | 4 | -2147483648 .. 2147483647 |
float | 4 | 4 | -3.4028235e+38f .. 3.4028235e+38f |
long | 8 | 8 | -9223372036854775808 .. 9223372036854775807 |
double | 8 | 8 | -1.7976931348623157e+308 .. 1.7976931348623157e+308 |
boolean | 4 | 1 | false, true |
Объекты
Для описания экземпляров массивов Hotspot использует класс arrayOopDesc, для описания остальных Java-классов используется класс instanceOopDesc. Оба эти класса наследуются от oopDesc и оба содержат методы для вычисления размера заголовка. Так например a instabceOopDesc вычисляет размер заголовка (в машинных словах) следующим образом:
где HeapWordSize определяется как размер указателя. В зависимости от архитектуры CPU 4 и 8 байт для x86 и x86_64 (в Oracle именуют x64) соответственно.
Чтобы понять размер instanceOopDesc надо заглянуть в oopDesc, так как в самом instanceOopDesc никаких полей не объявлено. Вот что мы там увидим:
В файле oopsHierarchy.hpp объявлены необходимые типы данных для работы с иерархией объектов oop (ordinary object pointer). Посмотрим как объявлены те типы, которые используются в oopDesc:
То есть это два указателя (читай два машинных слова) для конкретной архитектуры — так называемое маркировочное слово (mark word) и адрес (который может быть представлен указателем или смещением) на метаданные класса.
Идея этого union metadata состоит в том, что при включенной опции будет использоваться 32х битное смещение (_compressed_klass) а не 64х битный адрес (_klass).
Получается размер заголовка java-объекта 8 байт для x86 и 16 байт для x86_64 в не зависимости от параметра UseCompressedOops:
Архитектура | -XX:+UseCompressedOops | -XX:-UseCompressedOops |
---|---|---|
x86 | 8 байт () | |
x86_64 | 16 байт () |
Массивы
В arrayOopDesc размер заголовка вычисляется следующим образом:
где
- align_size_up — инлайнер для выравнивания первого аргумента по второму. Например .
- length_offset_in_bytes — возвращает размер заголовка в байтах в зависимости от опции . Если она включена, то размер равен = 8 (4 + 4) байт для x86 и 12 (8 + 4) байт для x86_64. При выключенной опции размер равен = 8 байт для x86 и 16 байт для x86_64.
- заметьте, что к вычисленному размеру прибавляется . Это делается для того чтобы «зарезервировать место» под поле length массива, так как оно явно не определено в классе. При включенной ссылочной компрессии (актуально только для 64x битной архитектуры) это поле займет вторую половину поля _klass (см. класс oopDesc)
Посчитаем, что у нас получается. Размер заголовка массива после выравнивания:
Архитектура | -XX:+UseCompressedOops | -XX:-UseCompressedOops |
---|---|---|
x86 | 12 байт () | |
x86_64 | 16 байт () | 24 байта () |
Класс Character
Класс в первую очередь интересен большим количеством утилитных статических методов, которые позволяют проверять символы на принадлежность разным категориям.
Примеры
Методы | Описание |
---|---|
Проверяет, является ли символ символом алфавита | |
Является ли символ буквой | |
Является ли символ цифрой | |
Является ли символ пробелом, символом переноса строки или смены параграфа (коды: 12, 13, 14) | |
Является ли символ разделителем: пробел, tab, и т.д. | |
Символ в нижнем регистре — строчные буквы? | |
Символ в верхнем регистре — заглавные буквы? | |
Преобразует символ в нижний регистр | |
Преобразует символ в верхний регистр |
Особенностью данных методов является то, что они работают со всеми известными алфавитами: символы арабских цифр будут определяться как цифры и т.п.
Присваивание целых и вещественных чисел
Было бы плохо, если бы целые числа можно было присваивать только переменным типа , а вещественные — только переменным типа . Хотелось бы иметь возможность преобразовывать одни числа в другие. И в Java такая возможность есть.
Во-первых, переменным типа можно присваивать как вещественные, так и целые числа. При присваивании целых чисел они просто преобразовываются в вещественные. Хотя иногда при этом возможна небольшая потеря точности.
Команда | Примечание |
---|---|
В переменной хранится значение | |
В переменной хранится значение | |
В переменной хранится значение |
Во-вторых, если в каком-то выражении участвуют целое и вещественное число, целое сначала преобразуется в вещественное и только потом взаимодействует с другим вещественным числом.
Команда | Примечание |
---|---|
В переменной хранится значение | |
На экран будет выведено число | |
На экран будет выведено число |
И наконец, есть возможность присваивать переменным типа вещественные числа. Дробная часть числа при этом отбрасывается — число округляется вниз до целого.
Также компилятор требует, чтобы этот факт программист задокументировал явно (чтобы другие программисты понимали, что тут происходит отбрасывание дробной части). Общий вид этого выражения в коде такой:
Присваивание переменной типа вещественного числа
Примеры:
Команда | Примечание |
---|---|
В переменной хранится значение | |
В переменной хранится значение | |
В переменной хранится значение |
Интерфейс
Интерфейс в Java относится к абстрактным типам данных. Они позволяют манипулировать коллекциями Java независимо от деталей их представления.
Кроме того, они образуют иерархию в объектно-ориентированных языках программирования.
//Generic interface definition interface GenericInterface<T1, T2> { T2 PerformExecution(T1 x); T1 ReverseExecution(T2 x); } //A class implementing generic interface class Genericclass implements GenericInterface<String, Integer> { public Integer PerformExecution(String x) { //execution code } public String ReverseExecution(Integer x) { //execution code } }
Clone
- Метод сlone нужен для копирования объекта.
- В методе clone присутствует защищенный модификатор доступа.
- Для вызова метода clone объекту требуется реализация интерфейса Cloneable. В противном случае выбрасывается исключение CloneNotSupportedException.
- Интерфейс Cloneable является маркерным, то есть методы не определяют интерфейс, а говорят классу об особом отношении.
- Плюс такого интерфейса: можно копировать только объекты, доступные для клонирования.
- Если какое-то поле объекта ссылается на другой объект, то делаем поверхностную копию. В ней копируется только адрес памяти, т.е. используется один и тот же объект.
- При глубоком копировании происходит создание объекта и новое динамическое распределение памяти.
Не обращайте внимание на оператора try — к нему мы вернемся позже
Методы
Универсальные методы очень похожи на универсальные классы. Они отличаются друг от друга только одним аспектом, заключающимся в том, что информация о области действия или типе находится только внутри метода. Универсальные методы вводят свои параметры типа.
public static <T> int countAllOccurrences(T[] list, T element) { int count = 0; if (element == null) { for ( T listElement : list ) if (listElement == null) count++; } else { for ( T listElement : list ) if (element.equals(listElement)) count++; } return count; }
Если вы передадите список String для поиска в этом методе, он будет работать нормально. Но если вы попытаетесь найти число в списке строк, это даст ошибку времени компиляции.
Методы класса
В начале статьи я упомянул, что наши домашние животные могут перемещаться и есть. В отличие от параметров вроде веса и клички, это уже не свойства объекта, а его функции. В классе эти функции обозначают как методы.
Метод класса — это блок кода, состоящий из ряда инструкций, который можно вызывать по его имени. Он обязательно содержит возвращаемый тип, название, аргументы и тело метода.
Синтаксис метода в Java:
Строка возвращаемыйТип показывает, какого типа данные вернёт метод. Например, если в качестве возвращаемого типа мы поставим тип String, то метод должен будет вернуть строку, а если int — целое число.
Чтобы вернуть значение из метода, используется специальное слово return. Если мы хотим, чтобы метод ничего не возвращал, то вместо возвращаемого типа нужно использовать специальное слово void.
Аргументы — то, что нужно передать в метод при его вызове. Мы можем указать сколько угодно параметров через запятую либо не указывать ни одного.
Для примера напишем простейший метод с именем sum (пока что не в нашем классе Pet), который складывает два переданных числа и возвращает их результат:
Возвращаемый тип метода int, он указан перед именем sum. Далее идут два аргумента a и b, у обоих также указан тип int
Важно помнить, что возвращаемый тип и тип переменных не обязательно должны совпадать
Аргументы метода работают как обычные переменные — за пределами метода к ним никак нельзя получить доступ. Внутри метода мы складываем значения из переменных a и b, записываем полученное значение в переменную c. После этого мы возвращаем значение переменной c — только оно доступно вне метода.
Вот пример:
Мы передали в метод sum два значения 1 и 2, а на выходе получили результат их сложения 3. Также можно создать метод, который принимает значение типа String, а возвращает длину этой строки:
В этом случае у нас возвращаемый типа int, а параметр str — типа String.
Попробуем использовать этот метод:
Также мы можем создать метод, который ничего не возвращает, а просто печатает переданное слово в консоль:
Либо метод, который ничего не принимает на вход, а просто печатает «Привет!»:
В методах, которые ничего не возвращают, слово return можно опустить.
Обратите внимание, что return полностью прекращает выполнение метода:
Теперь попробуем вызвать этот метод, передав в него число 3:
В этом случае мы ничего не увидим в консоли, так как 3 меньше 5, а значит, отработает блок if и произойдёт выход из метода с помощью слова return.
Но если передадим 6, увидим нашу надпись «Привет!»:
Основы класса Integer
Поскольку класс Integer имеет широкую функциональность, мы решили разделить данное руководство на разделы.
Как создать экземпляр класса Integer
Есть два способа создать экземпляр класса Integer. Первый способ – использовать ключевое слово new:
Integer secondInteger = new Integer(100);
Второй способ создать — использовать функцию автоупаковки (autoboxing) языка Java, которая конвертирует примитивный тип данных в соответствующий класс-обёртку:
Integer sampleInteger = 100;
Тест на равенство объектов Integer
Объекты Integer являются обёрткой для примитивного типа int. Поскольку они являются объектами, то оператор == не будет работать. Рассмотрим приведенный ниже отрывок кода:
Integer firstInteger = 100; Integer secondInteger = new Integer(100); System.out.println(firstInteger==secondInteger);
Поскольку мы имеем дело с объектами Integer, оператор == больше не применим. Как же провести сравнение двух Java объектов Integer? Рассмотрим приведенный ниже отрывок кода, демонстрирующий это:
Java-программа для проверки объектов Integer на равенство
package com.javatutorialhq.java.examples; /* * Пример программы для проверки объектов Integer на равенство */ public class IntegerTestEquality { public static void main(String[] args) { // создаём объекты Integer Integer firstInteger = 100; Integer secondInteger = new Integer(100); // проверка на равенство System.out.println(firstInteger.equals(secondInteger)); } }
Максимальное и минимальное значения Integer
Чтобы найти максимальное и минимальное значения Integer, мы обратимся к двум его полям. Максимальное значение объекта Integer (2147483647) может быть найдено с помощью вызова Integer.MAX_VALUE, а минимальное значение Integer (-2147483648) – через обращение к Integer.MIN_VALUE.
Рассмотрим метод parseInt(String s), который принимает строку в качестве аргумента и конвертирует её в объект Integer. Если мы передадим строковое значение, которое имеет целочисленный эквивалент, превышающее максимальное значение в Integer.MAX_VALUE? Грубым примером такого сценария может служить приведенный ниже код:
Integer intValue = Integer.parseInt("2147483648");
Мы передали в метод parseInt аргумент, который на 1 больше максимального значения. Поэтому если мы попытаемся выполнить этот отрывок кода, компилятор выдаст исключение NumberFormatException:
Exception in thread "main" java.lang.NumberFormatException: For input string: "2147483648" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:587) at java.lang.Integer.parseInt(Integer.java:615) at com.javatutorialhq.java.examples.IntegerTestEquality.main(IntegerTestEquality.java:12)
Как использовать статичные методы класса Integer
Большинство методов класса Integer статичные, поэтому имеет смысл разобраться, как получить доступ к ним. Не статичные методы используются так:
Integer intValue = Integer.parseInt("2147"); System.out.println(intValue.byteValue());
Статические методы не должны использоваться таким образом, а должны вызываться так как показано ниже:
System.out.println(Integer.max(1243, 1245));
Нестатические методы вызываются через переменная.метод. Статичные вызываются через Integer.метод(аргументы…).
Литералы символов
В коде можно задавать не только строковые литералы, но и литералы из отдельных символов. В данном случае речь идет не о строке, состоящей из одного символа, а о литералах типа .
Символьный литерал обрамляется одинарными кавычками, в отличие от строки. Внутри одинарных кавычек обязательно должен быть символ и только один. Не может быть пустых одинарных кавычек.
Примеры:
Код | Пояснение |
---|---|
Литерал типа char. Содержит латинскую букву A. | |
Литерал типа char. Содержит символ @ | |
Литерал типа char. Содержит иероглиф японского алфавита. Да, так тоже можно. | |
Литерал типа char. Содержит символ кодировки Unicode, заданный его номером. |
В последнем примере задается символ из кодировки Unicode с помощью специальной записи: сначала идет префикс , затем 4 шестнадцатеричных символа. Детальнее об этом в ближайших лекциях.
Загрузка статического и динамического класса
- Добавление класса для запуска в JVM называется загрузкой класса.
- Классы загружаются статично с помощью нового оператора.
- Первый класс загружается через метод static main(). Затем подгружаются остальные классы.
- В серверных проектах отсутствует main(), поскольку сервер сам отвечает за всю инфраструктуру. Первый класс для загрузки отмечается в config файле. Довольно часто фреймворк реализует метод main() и предоставляет API. Пример: Контейнерный класс вызывает метод init() в сервлетах.
- main нужен для запуска Java-программы из командной строки в JVM.
- Если при загрузке статического класса не находится ссылка на класс, то выбрасывается NoClassDefinationFoundException.
- Динамические классы загружаются через программный вызов при выполнении. Пример: Class.forName(String ClassName);
- ClassNotFoundException выбрасывается при загрузке динамического класса.
Конструкторы
- Их единственная цель — создавать экземпляры класса. Они вызываются в процессе создания объекта класса.
- Если конструктор с аргументами определен в классе, то нельзя будет работать со стандартным конструктором без аргументов (no-argument constructor) — придется их прописать.
- Java не поддерживает конструктор копирования.
- Имя конструктора и класса совпадает.
- Если конструктор вызывается из другого конструктора с синтаксисом this, то речь идет именно об этом объекте.
- В Java есть стандартный конструктор.
Приватный конструктор:
- Защищает класс от явного превращения в экземпляр.
- Построение объекта возможно только внутри конструктора.
- Используется в шаблоне «Одиночка» (Singleton).
Вопрос: Можно ли синхронизировать конструкторы в Java?
Нет. В Java запрещен многопоточный доступ к конструкторам объекта, поэтому необходимость в синхронизации отсутствует.
Вопрос: Наследуются ли конструкторы? Может ли подкласс вызывать конструктор родительского класса?
Конструкторы не наследуются. При переопределении конструктора суперклассов нарушается инкапсуляция языка. Конструктор родительского класса вызывается ключевым словом super.