Рубрики
Без рубрики

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

Добро пожаловать обратно в другой учебник по Java! Если вы следите за ходом игры, значит, вы только что закончили играть в aro… С пометкой java, новички, информатика.

Добро пожаловать обратно в другой учебник по Java! Если вы следите за ходом событий, значит, вы только что закончили играть с числами на панели взаимодействий DrJava. В этом уроке мы дадим некоторый контекст некоторым примерам из предыдущего урока. В частности, мы рассмотрим примитивные типы Java и их роль в создании переменных. Давайте начнем!

Понятия

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

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

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

variableType variableName; // Declaration
variableName = variableValue; // Definition

Приведенный выше синтаксис – это то, как мы создаем и храним данные в переменной. Мы начинаем с объявления типа данных, которые мы хотим сохранить, за которым следует их имя. Эта часть синтаксиса называется переменной declaration . Затем мы определяем переменную, используя оператор присваивания ( = ) и некоторое значение. Конечно, гораздо проще создавать переменные в одной строке:

тип переменной; В Java мы можем определить переменную, используя один из восьми встроенных типов данных, которые мы называем примитивными типами : int , двойной , символ , байт , короткий , длинный , плавающий и логическое значение/| . Например, мы могли бы определить целое число следующим образом:

int height = 17;

В этом случае мы определили переменную height со значением 17. Естественно, нам нужно будет ознакомиться со всеми восемью примитивными типами, чтобы мы могли использовать их соответствующим образом.

Реляционные операторы Java

Чуть выше мы говорили о хранении числового значения в переменной. Тем не менее, Java может делать гораздо больше, чем просто хранить числа. Например, мы можем сравнивать числа с помощью реляционных операторов.

В предыдущем уроке мы познакомились с одним из этих операторов: == . Кроме того, мы можем сравнивать значения, используя != , < , <= , > и >= . Попробуйте некоторые из следующих примеров:

6 > 7  // 6 is greater than 7 (false)
110 >= 54  // 110 is greater than or equal to 54 (true)
95 < 96  // 95 is less than 96 (true)
63 <= 100  // 63 is less than or equal to 100 (true)

Как вы, наверное, заметили, результатом каждой из этих операций является логическое значение: true или false . В будущем мы увидим, что эти операторы используются для управления всеми видами логики.

Арифметические операторы Java

В то время как реляционные операторы – это весело, нам нужны арифметические операторы, чтобы сделать наши выражения более интересными. До этого момента мы вводили арифметические операторы случайным образом, толком не объясняя их. К счастью, мы рассмотрим все наиболее распространенные арифметические операторы Java: + , - , * , / , % .

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

2 + 3  // 2 plus 3 (5)
11 - 5  // 11 minus 5 (6)
13 * 2  // 13 times 2 (26)
6 / 3 // 6 divided by 3 (2)
11 % 2  // remainder of 11 divided by 2 (1)

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

2.0 + 3.0  // 2.0 plus 3.0 (5.0)
11.0 - 5.0  // 11.0 minus 5.0 (6.0)
13.0 * 2.0  // 13.0 times 2.0 (26.0)
6.0 / 3.0 // 6.0 divided by 3.0 (2.0)
11.0 % 2.0  // ERROR! Can't compute remainder on doubles

Как мы увидим в следующем разделе, все становится странным, когда мы смешиваем типы в наших выражениях.

Усечение

Хотя арифметика может показаться простой, есть некоторые подводные камни, о которых мы должны знать. В конце концов, чего мы ожидаем, когда начнем смешивать примитивные типы? Например, следующие выражения возвращают разные результаты:

1 + 2  // 3
1 + 2.0  // 3.0

Это может показаться глупым, но это различие может иметь последствия. Например, что произойдет, если мы заменим сложение на деление? Как выясняется, что-то вроде 1/2 приведет к значению 0. В информатике мы называем это усечением .

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

Хотя усечение может сбивать с толку и противоречить интуиции, оно пригодится в некоторых случаях, таких как сопоставление – мы обязательно столкнемся с этим позже.

Во всяком случае, пока наши типы непротиворечивы, арифметика довольно проста. Однако, если мы вынуждены смешивать совместимые типы, такие как integer и double, Java преобразует весь результат в самый широкий тип. Другими словами, результатом вычисления будет тип, содержащий наибольшее количество битов.

Числовые Ограничения

Еще одна потенциальная проблема с арифметикой – это обернуть вокруг . Как выясняется, числа в компьютерных системах имеют пределы, и вычисления иногда могут превышать эти пределы.

Если у вас была возможность прочитать о 8 примитивных типах , то вы будете знать, что есть быстрый способ проверить пределы каждого примитивного типа. В качестве обновления мы можем определить максимальное значение целого числа, используя следующий фрагмент кода:

Integer.MAX_VALUE

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

Integer.MIN_VALUE

Ради забавы давайте посмотрим, что произойдет, когда мы выйдем за эти пределы:

Integer.MAX_VALUE + 1 // Prints -2147483648
Integer.MIN_VALUE - 1 // Prints 2147483647

Разве это не странно? Мы только что впервые наблюдали integer wraparound . Другими словами, как только мы достигнем предела примитивного типа, мы перейдем на другую сторону. Имейте это в виду, когда мы будем двигаться вперед.

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

Типовое литье

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

Допустим, у нас было вычисление, которое привело бы к удвоению, но мы не заботились о десятичном результате. Мы можем снизить точность, используя приведение типа к целому числу. Это используется повсеместно в коде, но хорошим примером может быть реализация округления. Без каких-либо знаний о потоке управления мы можем реализовать округление:

int round = (int) (7.6 + 0.5);

В этом примере число, которое мы пытаемся округлить до ближайшего целого числа, равно 7,6. Если десятичное число меньше .5, мы хотим, чтобы результат округлился в меньшую сторону. Аналогично, если десятичное число равно .5 или больше, мы хотим, чтобы результат округлялся в большую сторону.

Добавляя .5, мы заставляем 7.6 превратиться в 8.1. Затем typecast усекает десятичную точку, что приводит к нашему правильно округленному целому числу. Если бы число было равно 7,4, вычисление привело бы к значению 7,4 до 7,9. Затем приведение типов приведет к усечению десятичного числа.

Имея это в виду, мы рассмотрели практически все, что нам может понадобиться знать о примитивных типах Java.

Практика

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

  • Объявления и определения переменных
  • 8 примитивных типов: boolean , int , double , float , byte , short , long , обуглить
  • 5 арифметических операторов: + , - , * , / , %
  • 5 реляционных операторов: == , >= , > , < , <=
  • Усечение
  • Типовое литье
  • Числовые ограничения

На этом этапе мы сведем все это вместе с некоторыми примерами. На панели взаимодействия попробуйте выполнить следующие действия:

char letter = 'b';

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

boolean hasMoney = true; 
int hour = 7; 
double height = 13.7; 
float gravity = 9.81f; 
long sixBillion = 6000000000L;

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

hour + height;

Имена переменных не имеют большого смысла, но это совершенно законно и приведет к 20.7. Однако, если мы попробуем что-то вроде:

hasMoney + hour;

В конечном итоге мы получим ошибку. Это потому, что мы пытаемся добавить логическое значение к целому числу. Между тем, следующее полностью законно в Java:

char gravity = 'g'; 
char speedOfLight = 'c'; 
gravity + speedOfLight;

Мы действительно можем сложить эти символы вместе, что даст 202 или “Ê”. Поскольку тип char на самом деле является числовым значением, мы можем суммировать их как целые числа.

Добавление символов особенно удобно, если мы хотим сравнить символы для упорядочения. Например, две буквы можно сравнить в алфавитном порядке, сравнив их числовые значения. Полный список всех доступных символов ASCII и их значений можно найти здесь .

В качестве дополнительного примечания, символы Java являются 16-разрядными, что дает им гораздо большее разнообразие, чем 256 символов ASCII. Кроме того, примитивный тип char является единственным примитивным типом Java, который не имеет знака.

Но А Как Насчет Струн?

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

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

Чтобы проверить эту концепцию, попробуйте выполнить следующее на панели взаимодействия DrJava:

int x = 5; 
int y = 5; 
y == x;

Обратите внимание, что это сравнение возвращает значение true, как и ожидалось. Интуитивно понятно, что 5 равно 5. Теперь попробуйте выполнить следующее:

String firstName = "Leroy"; 
String lastName = "Leroy"; 
firstName == lastName;

В этом примере мы определяем два компонента чьего-либо имени: Лерой Лерой. Интуитивно мы могли бы подумать, что сравнение обоих имен вернет true. В конце концов, оба имени состоят из одних и тех же букв, и оба имени чувствительны к регистру. Однако мы получаем шокирующий результат false .

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

String firstName = "Leroy"; 
String lastName = "Jenkins"; 
firstName = lastName; 
firstName == lastName;

В этом случае сравнение с использованием == приводит к true. Конечно, сравнение значений одно и то же, так почему же на этот раз оно возвращает true? В следующем уроке мы более подробно рассмотрим строки и то, что на самом деле происходит, когда мы проводим сравнение с помощью == .

Будь осторожен! Если вы используете практически любой инструмент, кроме панели взаимодействий DrJava, вы можете обнаружить, что такие выражения, как “Лерой” верните значение true. Это связано с особой функцией Java, называемой интернирование строк (Спасибо, Ивен ) что гарантирует, что повторяющиеся строковые константы имеют одну и ту же ссылку. Другими словами, мы по-прежнему не сравниваем содержимое строки. Подробнее об этом позже!

Оригинал: “https://dev.to/renegadecoder94/primitive-types-and-variables-in-java-3gjm”