В предыдущей статье мы говорили о типах данных, а теперь поговорим о вытекающей из этого теме, о переменных.
Переменная - это поименованная область памяти, в которую мы можем сохранить данные, осуществлять доступ к этим данным или изменять их. Простыми словами, переменная в программировании, и в Java в том числе, является основной единицей хранения информации. В Java у переменной должен быть тип, имя и значение.
![](https://habrastorage.org/getpro/habr/upload_files/295/b42/919/295b42919a03d0ae1e065aeb917db360.png)
На скриншоте выше продемонстрирован пример создания переменных.
Тип - это тип данных переменной, которую необходимо создать. В примере используются примитивные типы данных, рассмотренные в предыдущей статье. Однако, переменная может быть не только примитивного типа. Переменная может являться экземпляром какого-либо класса. Изучать классы мы будем в следующих статьях.
Имя или Идентификатор - любую переменную нужно как-то обозвать. А даем мы имя переменной сразу после указания типа данных. Важно! Именем переменной может быть любая последовательность букв, цифр, но имя не может начинаться с цифры! При наименовании переменной так же учитывается регистр символов. abc и ABC будут разными именами. Еще можно встретить переменные, имя которых начинается с символа валюты доллара: $
Например: double $pi = 3.14;
Такое можно увидеть в авто-генерируемых участках кода. Живые люди, насколько мне известно, так не пишут.
Давайте сразу научимся давать имена переменным правильно. Существует документ Java Code Conventions. В нем указаны правила к написанию кода на Java. Нужно это для того, что бы Java код в разных проектах был написан в едином стиле. Таким образом, новоприбывший на проект программист не будет отвлекаться на новый стиль кода, ведь он будет оформлен так же, как и на других проектах. Эти правила работают и при нейминге переменных.
Итак, переменные принято называть в lowerCamelCase стиле. Сейчас покажу как хорошо, а как плохо:
![](https://habrastorage.org/getpro/habr/upload_files/fa9/416/f81/fa9416f811e8d66ea43bac145007cb4c.png)
Как вы могли заметить, в примере, в имени переменной используется символ подчеркивания _
. На практике допускается использовать такой символ только для имен констант. Чем константа отличается от переменной? Переменная на то и переменная, что ее значение изменчиво и всегда можно присвоить другое:
![](https://habrastorage.org/getpro/habr/upload_files/3c9/dff/a35/3c9dffa357e7abf54dfbdbbb9bf29b6f.png)
Вот было значение 1998, а на следующей строке стало 2000. А вот с константой так не получится. Константа гарантирует, что ее значение не изменится на протяжении всего времени выполнения программы. Как создать константу? Очень просто:
![](https://habrastorage.org/getpro/habr/upload_files/f16/065/a48/f16065a482a753931733fd22d226378a.png)
Нужно всего лишь дописать ключевое слово final
перед типом данных переменной. Для простоты понимания, мы как бы "финализируем" значение переменной и говорим, что это значение конечное.
Обратим внимание на имя константы. Когда мы даем имя константе, то должны делать это в стиле SCREAMING_SNAKE_CASE. Давайте исправим мой код:
![](https://habrastorage.org/getpro/habr/upload_files/a58/4b1/01d/a584b101ddf3ff0a8ad32a09b6f5fcbc.png)
В целом, вас никогда не погладят по головке за правильный нейминг в коде. Подразумевается, что это нечто естественное при написании кода. Как правила этикета у людей. А вот если вы будете называть ваши переменные и константы абы как, получите незамедлительного леща.
Инициализация переменных
У всех переменных из моих примеров уже было присвоено начальное значение. Процесс присвоения начального значения называется инициализацией переменной. И не обязательно инициализировать переменную во время ее объявления. Java позволяет сделать это и позже.
Во-первых, можно объявлять переменные через запятую (если они одинакового типа):
![](https://habrastorage.org/getpro/habr/upload_files/fa9/21f/7a2/fa921f7a21799efcf53a0be662a10012.png)
При этом, смотрите, мы можем некоторые из них инициализировать прямо во время объявления. А теперь инициализируем оставшиеся:
![](https://habrastorage.org/getpro/habr/upload_files/c2f/476/bf9/c2f476bf9e8b59968432760f011b0957.png)
Для инициализации переменных типа char
я использовал цепочку присваиваний. Да, и так тоже можно. Хотя используется очень редко.
Если мы попытаемся провести какую-то операция с переменной, у которой нет значения, то получим ошибку.
Оператор присваивания
Важно запомнить, что если вы где-то в коде Java, а также во многих других языках, увидите знак равенства =
, вы должны понимать, что это не сравниваются два значения. Вы должны понимать что это оператор присваивания. Его задача: взять значение, которое стоит справа от него, и записать в память переменной, которая стоит слева от него, или другими словами присвоить. Важно, чтобы значения справа и слева были одного типа данных в противном случае получаем ошибку.
Литералы
Видели, в моих примерах выше, я писал значение переменной с типом long
не просто 1998
а 1998L
? Сейчас расскажу, что это за L
в конце.
В Java постоянные значения задаются литеральным представлением. Простым языком, при помощи определенных символов мы можем указывать тип данных. Вот например, при работе с целочисленными литералами нам не нужны никакие литералы. Мы просто пишем число 1998;
и Java понимает, что это целочисленное значение.
Целочисленные литералы по умолчанию создаются в виде значения типа int
, и это значение можно присваивать всем целочисленным типам данных без проблем, в случае, если это значение не выходит за пределы допустимых значений (в предыдущей статье мы говорили о диапазонах значений у разных типов данных). Но что делать, если мы хотим указать целое число, которое больше пределов числа типа int
? В этом случае есть возможность создать литерал типа long
просто указав в конце символ L
. Я мог и не писать 1998L
, потому что число 1998
вполне помещается в диапазон значений типа данных int
. А теперь, я вдруг захотел присвоить переменной типа long
значение, скажем, в девять миллиардов. Число не маленькое и оно выходит за пределы максимального значения типа int
.
![](https://habrastorage.org/getpro/habr/upload_files/fb9/75a/454/fb975a45412af7986fc7f14d63ff060e.png)
Вот тут нам понадобится литерал типа long
. При помощи символа L
, в конце целочисленного значения, мы явно указывается, что это значение будет типа long
, а следовательно и с большим диапазоном значений.
![](https://habrastorage.org/getpro/habr/upload_files/792/b5c/6e9/792b5c6e9f5ee8e3f9ab3c2fc2260acc.png)
Так, что еще за символы подчеркивания в значении переменной? Это всего-навсего декор. С JDK 7 допустимо указывать знаки подчеркивания, для разбиения больших чисел на разряды, для удобства чтения.
В вышеописанных примерах были литералы для целочисленных десятичных значений. А еще мы можем присвоить целому числу литерал в виде восьмеричного значения. Для этого вам нужно добавить в самом начале значения 0. Но в таком случае, логично, что это значение не сможет содержать цифры 8 и 9, поскольку они выходят за пределы восьмеричной системы счисления.
Мало того, еще мы можем использовать литерал шестнадцатеричных значений. Такие значения обозначают с начальным 0x или 0X, а цифры в пределах от 10 до 15 заменяются символами ABCDEF английского алфавита.
![](https://habrastorage.org/getpro/habr/upload_files/7c5/93b/915/7c593b915c8e4effcaa1ec9d0bd7c959.png)
С JDK 7 есть возможность указывать целочисленные литералы в двоичном виде. Для этого вначале значения нужно указать 0b или 0B и соответственно в значениях можно использовать только цифры 0 и 1. В реальности, вам навряд ли понадобятся литералы шестнадцатеричных, восьмеричного или двоичных значений. Однако, знать о них нужно.
Литералы дробных чисел
Литералы дробных чисел могут быть представлены в привычном для нас виде. Они состоят из целой и дробной части, которые разделены точкой. Например: 10.9;
.
Но существует и экспоненциальная форма записи этих чисел в виде 2.34e12;
Где число после символа ‘e’ обозначает степень 10-ти. Простыми словами, мы записали 2 целых и 34 сотых умноженное на 10 в 12 степени.
По умолчанию литералы дробных чисел имеют тип double
, если хотим создать литерал типа float
, нужно указать символ f
или F
в конце значения. Как я уже сказал, по умолчанию, литерал будет типа double
, однако мы все же можем указать это явно, дописав в конце значения символ d
или D
. Особого смысла это иметь, конечно же, не будет.
![](https://habrastorage.org/getpro/habr/upload_files/4ae/3dc/b83/4ae3dcb834530bcf5eb23317419d6d25.png)
Как и в случае с целочисленными значениями, литералы с плавающей точкой поддерживают нижнее подчеркивание начиная с JDK 7.
Логические литералы
С логическими литералами все просто, они поддерживают только два логических значения true
или false
.
Символьные литералы
Для символьных литералов, которые присутствуют на вашей клавиатуре вы можете использовать одинарные кавычки, обернув ими необходимый вам символ введенный с клавиатуры.
![](https://habrastorage.org/getpro/habr/upload_files/c4c/53f/fed/c4c53ffed2037140b562fd2703e340a3.png)
Я не просто так обратил ваше внимание на символы с клавиатуры. Ведь существуют и такие символы, которых на клавиатуре нет, да и на символы они не похожи. Сейчас разберемся.
Как я уже говорил, тип char
целочисленный и может хранить в себе символы кодировки Unicode. Unicode - это стандарт кодировки символов, который присваивает каждому символу код, в виде положительного целочисленного значения. Поэтому, тип char
не может хранить отрицательные значения. А также, над типом char
можно выполнять операции сложения и вычитания. Не представляю, зачем кому-то может понадобиться выполнять арифметические операции над типом char
, но знайте, Java это позволяет. Мало того, коды символов английского алфавита (и многих других), расположены в порядке возрастания. Например, символу a соответсвует код 97, символу b - код 98. На основе этого можно сортировать символы по алфавиту.
А вот если символ нельзя ввести непосредственно с клавиатуры, то для ввода таких символов используют ряд управляющих последовательностей. Например, символ переноса строки ‘\n’. Существуют последовательности, которые существуют для ввода значений в восьмеричной и шестнадцатеричной форме. Например, мы захотели ввести букву tu катаканы смайлик: ツ. Берем и пишем:
![](https://habrastorage.org/getpro/habr/upload_files/4c2/bee/6d7/4c2bee6d7278dec318a48847a795e206.png)
В данной таблице вы можете посмотреть наиболее используемые последовательности символов:
![](https://habrastorage.org/getpro/habr/upload_files/405/6e7/476/4056e7476aea360418f9946421160289.png)
Когда-то давно, я писал статью про экранирование символом. Настоятельно рекомендую прочитать, как дополнительный материал. Узнаете много интересного.
Строковый литерал
Можно заключить последовательность символов в двойные кавычки и получить так называемую строку.
![](https://habrastorage.org/getpro/habr/upload_files/fcb/c73/ec3/fcbc73ec3f1fd74b9e80dd870142103a.png)
Про строки будет отдельная статья, через одну если быть точным. Там нам будет о чем поговорить, а пока просто имейте ввиду что ""
- это строковый литерал.
Динамическая инициализация
Пару слов о таком термине как динамическая инициализация. Ничего сложного, только звучит страшно.
Переменную можно инициализировать другой переменной. Также, допускается инициализация переменной результатом какого-то выражения.
![](https://habrastorage.org/getpro/habr/upload_files/c0f/e05/726/c0fe05726fbcb225f5a637069863f048.png)
Главное, чтобы тип данных выражения / инициализирующей переменной совпадал с типом данных целевой переменной.
Преобразование и приведение типов
Знаю, вы уже подустали, сделали массу перерывов и подходов. Обещаю, это последняя тема в этой статье.
Часто программисты сталкиваются с ситуацией, когда переменной одного типа приходится присваивать значение другого типа. Если оба типа данных совместимы, их преобразование будет выполнено автоматически. Для автоматического преобразования должно выполняться 2 условия:
![](https://habrastorage.org/getpro/habr/upload_files/c90/4b2/216/c904b22166c23a4e81253c6a7c20a975.png)
Не так страшен черт, как его малюют. Все очень просто. Например, тип long
достаточно велик чтобы поместить в себя тип int
и прочие целочисленные типы данных которые меньше long
.
На картинке выше, вы можете увидеть, какие типы данных вы можете преобразовать автоматически. Исходя из этого изображения, мы можем в переменную типа float
поместить значение типа long
. Звучит странно, давайте проверим:
![](https://habrastorage.org/getpro/habr/upload_files/33b/388/32f/33b38832ffab99001cd886fca07fe806.png)
Все работает. К сожалению, автоматическое преобразование не способно покрыть все потребности. Например если нужно тип int
преобразовать в byte
.
![](https://habrastorage.org/getpro/habr/upload_files/e6e/a02/e5b/e6ea02e5b0e34f4645fc88840043a63b.png)
Чтобы выполнить преобразование двух несовместимых типов данных, нужно воспользоваться приведением типов. Это явное преобразование одного типа в другой. И выглядит это вот так:
![](https://habrastorage.org/getpro/habr/upload_files/693/890/f72/693890f728c66e08d1f0e94514f5a394.png)
Нужно понимать, что преобразование вы проводите на свой страх и риск. Вы должны быть уверенным в том, что преобразуемое значение помещается в диапазон целевого типа. В противном случае вы получите некорректные данные.
Подводим итоги
В этой статье мы поговорили о многих важных вещах. Узнали, как создавать переменные и константы в Java, и чем они отличаются. Узнали о способах инициализации переменных. Разобрались с тем, что такое литералы и какие они бывают. А так же выполнили преобразование и приведение типов данных.
Скажем спасибо Егору за предоставленный материал.
В следующей статье мы будем изучать массивы. Если переменная - это вагон, то поездом будет массив. В общем, будет опять многобукав и многомерные массивы. Всем спасибо за внимание. Учитесь старательно!