Содержание

Примитивные типы [ править ]

В Java есть 8 примитивных типов, которые делят на 4 группы, вот они:

  1. Целые числа — byte, short, int, long
  2. Числа с плавающей точкой (иначе вещественные) — float, double
  3. Логический — boolean
  4. Символьный — char

Целочисленные типы [ править ]

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

ТипРазмер (бит)Диапазон
byte8 битот -128 до 127
short16 битот -32768 до 32767
char16 битбеззнаковое целое число, представляющее собой символ UTF-16 (буквы и цифры)
int32 битот -2147483648 до 2147483647
long64 битот -9223372036854775808L до 9223372036854775807L

Пример использования целочисленных типов:

Символы тоже относят к целочисленным типам из-за особенностей представления в памяти и традиций.

Типы с плавающей точкой [ править ]

ТипРазмер (бит)Диапазон
float32от 1.4e-45f до 3.4e+38f
double64от 4.9e-324 до 1.7e+308

Логический тип [ править ]

ТипРазмер (бит)Значение
boolean8 (в массивах), 32 (не в массивах используется int)true (истина) или false (ложь)

Ссылочные [ править ]

Ссылочные типы — это все остальные типы: классы, перечисления и интерфейсы, например, объявленные в стандартной библиотеке Java, а также массивы.

Строки [ править ]

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

Эта программа выведет:
Hello World
foo == bar ? true
foo равен bar ? true
foo == baz ? false
foo равен baz ? true

Обертки [ править ]

Если требуется создать ссылку на один из примитивных типов данных, необходимо использовать соответствующий класс-обертку. Также в таких классах есть некоторые полезные методы и константы, например минимальное значение типа int можно узнать использовав константу Integer.MIN_VALUE. Оборачивание примитива в объект называется упаковкой (boxing), а обратный процесс распаковкой (unboxing).

ТипКласс-обертка
byteByte
shortShort
intInteger
longLong
charCharacter
floatFloat
doubleDouble
booleanBoolean

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

Получить примитив из объекта-обертки можно методом Value.

Страницы

17 апр. 2015 г.

Примитивные вещественные типы Java — float, double

ТипСодержитПо умолчаниюРазмерДиапазонОбертки
вещественное знаковое0.032 bitsот 1.4E−45 до 3.4028235E+38Float
вещественное знаковое0.064 bitsот 4.9E−324 до 1.7976931348623157E+308Double

Вещественные числа в Java представлены типами данных float и double. Как показано в таблицах выше, float является 32 битным значением с плавающей точкой, с обычной точностью, а double представляет 64 битное значение с плавающей точкой, с двойной точностью. Количество бит отведенные под представление этих чисел смотрите в таблице выше. Оба типа соответствуют стандарту IEEE 754-1985, который определяет формат чисел и арифметические операции, применимые к этим числам. Но есть и небольшие отличия от этого стандарта. К обычным вещественным числам добавляются еще четыре значения:

  • положительная бесконечность, выражаемая константой POSITIVE_INFINITY и возникающая при переполнении положительного значения, например в результате операции умножения 3.0*6e307 или при делении на нуль;
  • отрицательная бесконечность NEGATIVE_INFINITY, возникающая при переполнении отрицательного значения, например в результате операции умножения -3.0*6e307 или при делении на нуль отрицательного числа;
  • «не число», записываемое константой NaN (Not a Number) и возникающее, например, при умножении нуля на бесконечность.
  • кроме того, стандарт различает положительный и отрицательный нуль, возникающий при делении на бесконечность соответствующего знака, хотя сравнение 0.0 == -0.0 дает в результате истину, true.

Операции с бесконечностями выполняются по обычным математическим правилам. Во всем остальном вещественные типы — это обычные вещественные значения, к которым применимы все арифметические операции и операции сравнения.

Вещественные литералы

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

Литералы с плавающей точкой можно также представить в экспоненциальной, или научной, нотации, в которой за числом следует буква e или E (показатель степени) и другое число. Второе число представляет степень десятки, на которую умножается первое число . Если же число записано в шестнадцатеричном формате, то экспонента это степень двойки . Например:

1.2345E02 // 1.2345 × 10 2 , или 123.45
1e-6 // 1 × 10 -6 , или 0.000001
6.02e23 // Число Авогадро: 6.02 × 10 23

Так же с Java 6, возможно записывать в шестнадцатеричном формате:

0xFp2 // 15×2 2 =60

Литералы с плавающей точкой по умолчанию являются значениями типа double . При включении значения типа float в программу за числом следует поставить символ f или F :

double d = 6.02E23;
float f = 6.02e23f;

В принципе литералы типа double можно тоже обозначать суффиксом d или D, но это особо не имеет смысла, так как вещественные литералы всегда по умолчанию double .

Большинство вещественных чисел, по самой их природе, нельзя точно представить каким-либо конечным количеством битов. Таким образом, необходимо помнить, что значения float и double являются только приближенными значениями представляемых ими чисел. float – это 32 битное приближение, которое дает как минимум 6 значимых десятичных разрядов, а double – это 64 битное приближение, которое представляет по крайней мере 15 значимых десятичных разрядов. На практике эти числа подходят для большинства вычислений с вещественными числами.

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

Бесконечные значения с плавающей точкой ведут себя вполне логично. Например, прибавление к бесконечности или вычитание из нее любого конечного значения дает бесконечность. Поведение отрицательного нуля почти не отличается от положитель ного нуля; фактически оператор равенства == сообщает о равенстве отрицательного и положительного нуля. Единственный способ отличить отрицательный нуль от по ложительного или обычного нуля – разделить на него какоелибо число. 1.0/0.0 дает положительную бесконечность, а деление 1.0 на отрицательный нуль дает отрицательную бесконечность. И наконец, поскольку NaN не является числом, оператор == сообщает, что это значение не равно ни одному другому числу, включая само значение ! Чтобы проверить, являются ли значения float и double нечисловыми (NaN), следует вызвать методы Float.isNaN() и Double.isNaN() .

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

Поскольку к вещественным типам применимы все арифметические операции и сравнения, целые и вещественные значения можно смешивать в операциях. При этом правило приведения типов дополняется такими условиями:

если в операции один операнд имеет тип double, то и другой приводится к типу double;

иначе, если один операнд имеет тип float, то и другой приводится к типу float;

в противном случае действует правило приведения целых значений.

Побитовые операции с вещественными типами не поддерживаются .

Операция деление по модулю (или остаток) определяется так же как и для целочисленных типов:
a % b = a — (a / b) * b

Так же для операции деления по модулю справедливо следующее выражение:

a = ((long)(a/b))*b+(a%b)

Вычисления чисел с плавающей точкой на одном и том же, а тем более на разных процессорах могут давать несколько разные результаты, поскольку виртуальная машина java выполняет эти операции на сопроцессоре (FPU), если он присутствует на устройстве. А в сопроцессоре обычно регистры для работы с плавающей точкой 80 бит, что шире даже чем double. Поэтому, если в эти регистры положить числа double, а потом опять вернуть их в double, то результаты могут быть разные для одинаковых чисел, по умолчанию java эту проблему не решает, то есть нет гарантии, что написанный код работающий с целочисленными типами будет давать одинаковый результат на разных процессорах. Это сделано потому, что желательно использовать сопроцессор для скорости вычислений. Результаты в этом случае могут немного различаться.

Чтобы результаты были на всех процессорах одинаковые, то следует использовать ключевое слово strictfp в декларации метода, например:

public static strictfp void main(String[] args)

В данном случае все что будет происходить в методе main, будет происходить без участия сопроцессора, будет строго округляться в пределах 64 бит и результат будет одинаковым на разных процессорах.

System.out.println(«April has » + month_days[3] + » days.»);

При запуске эта программа печатает количество дней в апреле, как это показано ниже. Нумерация элементов массива в Java начинается с нуля, так что число дней в апреле — это month_days [3].

April has 30 days.

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

public static void main(String args[]) <

System.out.println(«April has » + month_days[3] + » days.»);

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

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

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

double matrix [][] = new double [4][4];

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

double matrix [][] = new double [4][];

matrix [0] = new double[4];

matrix[1] = new double[4];

В следующем примере создается матрица размером 4 на 4 с элементами типа double, причем ее диагональные элементы (те, для которых х==у) заполняются единицами, а все остальные элементы остаются равными нулю.

public static void main(String args[]) < double m[][];

m = new double[4][4];

System.out.println(m[0][0] +» «+ m[0][1] +» «+ m[0][2] +» «+ m[0][3]);

System.out.println(m[1][0] +» «+ m[1][1] +» «+ m[1][2] +» «+ m[1][3]);

System.out.println(m[2][0] +» «+ m[2][1] +» «+ m[2][2] +» «+ m[2][3]);

System.out.println(m[3][0] +» «+ m[3][1] +» «+ m[3][2] +» «+ m[3][3]);

Запустив эту программу, вы получите следующий результат:

C : > Java Matrix

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

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

public static vo >

System.out.println(m[0][0] +» «+ m[0][1] +» «+ m[0][2] +» «+ m[0][3]);

System.out.println(m[1][0] +» «+m[1][1] +» «+ m[1][2] +» «+ m[1][3]);

System.out.println(m[2][0] +» «+m[2][1] +» «+ m[2][2] +» «+ m[2][3]);

System.out.println(m[3][0] +» «+m[3][1] +» «+ m[3][2] +» «+ m[3][3]);

Запустив эту программу, вы получите следующий результат:

С: > Java AutoMatrix

Теперь вы знаете, как работать с восьмью простыми типами языка Java. Вы видели, как нужно создавать объекты этих типов и знаете разрядности каждого из них. Вы знаете, как эти типы взаимодействуют и какие из них подходят для арифметических вычислений. Вы познакомились с типом boolean и почувствовали, что от символов мало пользы пока нет возможности группировать их вместе, образуя слова — к этому вопросу мы вернемся в главе 9, где познакомимся со строками. Мы не обошли своим вниманием массивы и видели, как можно создавать массивы из массивов. В следующей главе мы научимся выполнять над всеми этими типами различные операции.

«>