Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие Java.doc
Скачиваний:
17
Добавлен:
07.09.2019
Размер:
569.34 Кб
Скачать

Операции сдвига

Операции сдвига применяются только к переменным целого типа. Эти операции предназначены для сдвига с учетом знака влево (<<) или вправо (>>) на число бит, указанное после оператора. Java также добавлен беззнаковый сдвиг вправо >>>, который использует дополнение нулями: независимо от знака, в старшие биты вставляются нули.

Если вы сдвигаете char, byte или short, это переводится в int перед сдвигом, а результат будет типа int. Будут использоваться только пять младших бит с правой стороны. Это предохранит вас от сдвига на болешее число бит, чем есть в int. Если вы работаете с long, в результате вы получите long. Будут использоваться только шесть младших бит с правой стороны, так что вы не сможете сдвинуть на большее число бит, чем есть в long.

Сдвиг может быть скомбинирован со знаком равенства (<<= или >>= или >>>=). Однако, если это применяется к byte или short, корректный результат не будет получен. Происходит преобразование к int и правый сдвиг, далее происходит усечение, так как результат снова присваивается к той же переменной, так что в этих случаях вы получите -1.

Тернарный оператор ?:

Этот оператор используется в выражениях с тремя операндами.. Выражение имеет форму:

boolean_выражение ? значений_1 (если true) : значение_2 (если false)

Если boolean-выражение принимает значение true, вычисляется значение_1, иначе вычисляется значение_2. Вычисленное значение становится результатом операции. Например:

static int func(int n)

{ return n <5 ? i +5 : i -5;

}

Этот код более компактный, чем написанный без использования тернарного оператора:

static int func(int n) {

if (n < 5) return n +5;

else return n-5;

}

Оператор запятая

В Java оператор запятая используется только в циклах.

Одномерные массивы

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

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

Как и в других языках, массив − это совокупность переменных одного типа, хранящихся в смежных ячейках оперативной памяти.

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

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

float[] ms1, ms2;

Здесь определены две переменные − ссылки ms1 и ms2 на массивы типа float. Можно поставить квадратные скобки и непосредственно после имени переменной определяемой как ссылка:

int val = 1, ms3[];

Здесь определена переменная целого типа val, и объявлена ссылка mas на целочисленный массив.

Второй этап − определение. На этом этапе выделяется место в оперативной памяти для массива, и ссылка получает адрес массива. Для этой цели используется операция языка Java − new. Например,

ms1 = new float[3];  // ссылка на массив из 3 элементов типа float

ms2 = new float[15];  // ссылка на массив из 15 элементов типа float

ms3 = new int[30]; // ссылка на массив из 30 элементов типа int

Индексы массивов, как и в С, всегда начинаются с 0. Массив ms1 состоит из трех переменных ms1[0], ms1[1], ms1[2]. Индексы можно задавать любыми целочисленными выражениями, кроме типа long, например, ms1[i+j], ms1[i/3], ms1[i++]. Во время выполнения приложения виртуальная машина Java проверяет выход за границы массива. Если приложение пытается выйти за границы массива, генерируется исключение.

Третий этап − инициализация. На этом этапе элементам массива присваиваются значения.

ms1[0] = 1.03; ms1[1] = 0.5; ms1[2] = -3.59;

for (int i = 0; i < 15; i++) ms2[i] = i/2.5;

for (int i = 0; i < 30; i++) ms3[i] = 3*i;

Первые два этапа можно совместить:

double[] ms1 = new double[3], ms2 = new double[15]; 

int val = 1, ms3[] = new int[30];

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

double[] а = {0.01, -3.4, 2.89, 4.5, -6.7};

Можно совместить второй и третий этап:

а = new double[]{0.1, 0.2, -0.3, 0.45, -0.02};

Также можно создать безымянный массив, сразу же используя результат операции new, например:

System.out.println(new char[] {'J', 'a', 'v', 'a'});

Ссылка на массив не является частью описанного массива, ее можно перебросить на другой массив того же типа операцией присваивания. Например, после присваивания ms1=ms2 обе ссылки указывают на один и тот же массив из 15 вещественных переменных типа float и содержат один и тот же адрес. При этом массив, на который указывала ссылка ms1, может быть потерян, если на него не было других ссылок.

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

ar = null;

К ссылкам применимы также операции сравнения (= = и !=). Эти операция используются для сравнения адресов, содержащихся в ссылках.

Массивы в Java всегда определяются динамически.

Кроме ссылки на массив, для каждого массива автоматически определяется целая константа с одним и тем же именем length. Она равна длине массива. Префиксом этой константы является имя массива. Так, для сделанных ранее определений ms1,ms2 и ms3, константа ms1.length равна 3, константа ms2.length равна 15, a ms3.length равна 30. И они могут быть использованы, например:

for (int i = 0; i < ms1.length/2; i++)

{ ms1[i]+= ms1[ms1.length-1-i];

ms1[a.length-1-i]= ms1[i] – ms1[ams1.length-1-i];

ms1[i]-= ms1[ms1.length-1-i];

В данном фрагменте выполняется «переворот» массива ms1.

Ссылка исчезает по окончании блока. Однако объект, на который указывала ссылка, продолжает существовать. Это создавало в C++ проблемы, и было устранено в Java использованием сборщика мусора, который ”смотрит” на созданые с помощью new объекты, и при отсутствии ссылок на него освобождает память этого объекта. Когда объект более не нужен, он просто исчезнет. Это устраняет так называемую «утечку памяти».