Выбрать главу

byte а = 40;

byte b = 50;

byte с = 100;

int d = a* b / с;

Результат промежуточного выражения (а*b) вполне может выйти за диапазон допустимых для типа byte значений. Именно поэтому Java автоматически повышает тип каждой части выражения до типа int, так что для промежуточного результата (а* b) хватает места.

Автоматическое преобразование типа иногда может оказаться причиной неожиданных сообщений транслятора об ошибках. Например, показанный ниже код, хотя и выглядит вполне корректным, приводит к сообщению об ошибке на фазе трансляции. В нем мы пытаемся записать значение 50*2, которое должно прекрасно уместиться в тип byte, в байтовую переменную. Но из-за автоматического преобразования типа результата в int мы получаем сообщение об ошибке от транслятора — ведь при занесении int в byte может произойти потеря точности.

byte b = 50;

b = b* 2:

^Incompatible type for =. Explicit cast needed to convert int to byte.

(Несовместимый тип для =. Необходимо явное преобразование int в byte)

Исправленный текст:

byte b = 50;

b = (byte) (b* 2);

что приводит к занесению в b правильного значения 100.

Если в выражении используются переменные типов byte, short и int, то во избежание переполнения тип всего выражения автоматически повышается до int. Если же в выражении тип хотя бы одной переменной — long, то и тип всего выражения тоже повышается до long. Не забывайте, что все целые литералы, в конце которых не стоит символ L (или 1), имеют тип int.

Если выражение содержит операнды типа float, то и тип всего выражения автоматически повышается до float. Если же хотя бы один из операндов имеет тип double, то тип всего выражения повышается до double. По умолчанию Java рассматривает все литералы с плавающей точкой как имеющие тип double. Приведенная ниже про1рамма показывает, как повышается тип каждой величины в выражении для достижения соответствия со вторым операндом каждого бинарного оператора.

class Promote {

public static void main (String args []) {

byte b= 42;

char с = 'a’;

shorts = 1024;

int i = 50000;

float f = 5.67f;

doubled =.1234;

double result = (f*b) + (i/ c) - (d* s);

System, out. println ((f* b)+ "+ "+ (i / c)+ " -" + (d* s));

System, out. println ("result = "+ result); }

}

Подвыражение f*b — это число типа float, умноженное на число типа byte, поэтому его тип автоматически повышается до float. Тип следующего подвыражения i / с (int, деленный на char) повышается до int. Аналогично этому тип подвыражения d*s (double, умноженный на short) повышается до double. На следующем шаге вычислений мы имеем дело с тремя промежуточными результатами типов float, int и double. Сначала при сложении первых двух тип int повышается до float и получается результат типа float. При вычитании из него значения типа double тип результата повышается до double. Окончательный результат всего выражения — значение типа double.

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

class SimpleTypes {

public static void main(String args []) {

byte b = 0x55;

short s = 0x55ff;

int i = 1000000;

long l = 0xffffffffL;

char с = ’a’;

float f= .25f;

double d = .00001234;

boolean bool = true;

System.out.println("byte b = " + b);

System.out.println("short s = " +s);

System.out.println("int i =” + i);

System.out.println("long 1 = " + l);

System.out.println("char с =” + с);

System.out.println("float f = " + f);

System.out.println("double d = " + d);

System.out.println("boolean bool =” + bool); }

}

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

byte b = 85

shorts = 22015

int i = 1000000

long 1 = 4294967295

char с = a

float f = 0.25

double d=1.234e-005

boolean bool = true

Обратите внимание на то, что целые числа печатаются в десятичном представлении, хотя мы задавали значения некоторых из них в шестнадцатиричном формате.

3. МАССИВЫ

Массив - это группа переменных одного типа, доступ к которым осуществляется с помощью общего имени. Для объявления типа массива используются квадратные скобки. В приведенной ниже строке объявляется переменная month_days, тип которой — «массив целых чисел типа int».

int month_days [];

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

month_days = new int [12];

Итак, теперь month_days — это ссылка на двенадцать целых чисел. Ниже приведен пример, в котором создается массив, элементы которого содержат число дней в месяцах года (невисокосного).

class Array {

public static void main (String args []) {

int month_days[];

month_days = new int[12];

month_days[0] = 31;

month_days[l] = 28;

month_days[2] =31;

month_days[3] = 30;

month_days[4] =31;

month_days[5] = 30;

month_days[6] = 31;

month_days[7] = 31;

month_days[8] = 30;

month_days[9] = 31;

month_days[10] = 30;

month_days[ 11 ] = 31;

System.out.println("Апрель содержит” + month_days[3] +” дней.");} }

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

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

class AutoArray {

public static void main(String args[]) {

intmonth_days[] = { 31,28,31,30,31,30, 31, 31,30,31, 30, 31 };

System.out.println("Апрель содержит " + month_days[3] + " дней."); }

}

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

3.1. Многомерные массивы

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