© 2008 Наталия Македа
Все материалы блога защищены авторским правом. Любая перепечатка или использование материалов этого блога в коммерческих целях возможна лишь с письменного согласия автора. При некоммерческом использовании ссылка на блог обязательна.

воскресенье, 27 апреля 2008 г.

2. Операторы и присваивания (Выпуск 4)

2. Операторы и присвоения" (Operators and assignments)

Операторы в Java используются для разнообразных операций (всех необходимых). Все Javaоператоры перечислены в Таблице 2.1:


Таблица 2.1: Операторы Java в нисходящем порядке приоритетности массива

КатегорияОператоры
Унарные++ -- + - ! ~ ()
Арифметические* / %
+ -
Сдвиг<< >> >>>
Сравнение< <= > >= instanceof
== !=
Поразрядные& ^
Быстрого принятия решения&&
Условные?:
Присвоение= op=

2.1. Порядок вычисления

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

1. int [] a = { 4, 4 };
2. int b = 1;
3. a[b] = b = 0;

Какой элемент массива модифицирован? Какое значение b использовано для выбора элемента массива: 0 или 1? Согласно правилу вычисления слева направо самое левое выражение a[b] должно быть вычислено первым. Так что это a[1]. Затем вычисляется b, то есть активируется ссылка на переменную b. Затем вычисляется константа 0, что не требует никаких операций. Затем в вычисление включаются операторы. Вычисление при этом проводится в порядке приоритетности и ассоциацивности. Для присвоений ассоциативность - справа налево. Таким образом, сначала значение 0 присваивается переменной b, которая, в свою очередь, затем присваивается последнему элементу массива a.

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

2.2. Унарные операторы

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

  • Инкремент (увеличение значения на 1) и декремент (уменьшение значения на 1): ++ и --
  • Унарный плюс и минус: + и -
  • Поразрядное инвертирование: ~
  • Логическое дополнение: !
  • Приведение типа: ( )

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

Инкремент (увеличение значения на 1) и декремент (уменьшение значения на 1): ++ и --

Эти операторы изменяют значение выражения добавлением или вычитанием 1. Например, если переменная x типа int равна 10, то ++x (--x) равно 11 (соответственно, 9). Результат записывается в x.

В предыдущих примерах операторы находились перед переменной. Они могут находиться и после неё. И ++x, и x++ дают один и тот же результат, сохраняемый в x. Но значение всего выражения отличается. Например, если y = x++, то значение y равно исходному значению x. Если же y = ++x, то значение y на единицу больше, чем исходное значение x. В обоих случаях значение x увеличивается на 1.

Если инкремент (декремент) расположен слева от выражения, то выражение модифицируется перед тем (после того), как оно начинает участвовать в остальном вычислении. Это называется пре-инкремент (пре-декремент). Соответсвенно, если оператор находится справа от выражения, то в остальном вычислении участвует исходное значение этого выражения. И инкремент (декремент) происходит после того, как вычисление всего выражения завершено.

Таблица 2.2. показывает значения x и y после применения инкремента и декремента справа и слева.


Таблица 2.2: Примеры премодификации и постмодификации инкрементом и декрементом

КатегорияОператоры
Начальное значение xВыражениеИтоговое значение yИтоговое значение x
5y = x++56
5y = ++x66
5y = x--54
5y = --x44

Унарный плюс и минус: + и -

Унарные операторы + и - отличаются от обычных бинарных операторов + и -, которые трактуются, как сложение и вычитание. Унарный + не имеет никакого эфекта, кроме подчёркивания положительной природы численного литерала. Унарный - отрицает выражение (было положительным - стало отрицательным, было отрицательным - стало положительным). Примеры:

1. x = -3;
2. y = +3;
3. z = -(y + 6);

В примере единственное обоснование использования унарного плюса - подчёркивание, что переменной y присваивается положительное число. Общее выравнивание кода также более красиво с эстетической точки зрения :). Заметим, что в третьей строке унарный оператор применяется не к литералу, а к выражению. Таким образом, значение переменной z присваивается -9.

Поразрядное инвертирование: ~

Каждый примитивный тип Java представляется в виртуальной машине так, что представление не зависит от платформы. Это означает, что битовый шаблон, используемый для представления некоего отдельного числа, будет всегда тем же самым. Таким образом и манипулирование битами - процесс более эффективный, в силу независимости от платформы. Поразрядное инвертирование означает, что в двоичном представлении числа 0 заменяется на 1, а 1 - на 0.

Например, применение этого оператора к байту с содержимым 00001111 даст 11110000.

Логическое дополнение: !

Оператор ! инвертирует логическое значение выражения. Например, !true = false. Этот оператор часто используется в тестовой части if () конструкции. Эффект этого - изменение значения логического выражения. То есть обработчики if () и else могут быть легко обменяться местами. Рассмотрим два эквивалентных фрагмента кода:

1. public Object myMethod(Object x) {
2. if (x instanceof String) {
3. // do nothing
4. }
5. else {
6. x = x.toString();
7. }
8. return x;
9. }

и

1. public Object myMethod(Object x) {
2. if (!(x instanceof String)) {
3. x = x.toString();
4. }
5. return x;
6. }

В первом фрагменте, тестирование происходит в строке 2, но присвоение - в строке 6, если тест не пройдёт. Это сделано немного громоздко при помощи ветви else конструкции if/else. Второй фрагмент использует оператор логического дополнения, поэтому во второй строке тест инвертирован и может быть прочтён как Если x не строка. Если тест проходит, то обработка происходит в третьей строке и никакого отдельного else не требуется и результирующий код более краток и более читаем.

Приведение типа: ( )

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

Приведение типа применяется для изменения типа значений примитивного типа. Например, мы можем форсировать конвертацию double к int как, например, в следующем фрагменте:

int circum = (int)(Math.PI * diameter);

Здесь приведение типа выражается фрагментом (int). Если бы этот фрагмент отсутсвовал, то компилятор бы выдал ошибку, поскольку double значение, возвращаемое арифметическим выражением не может быть точно представлено int значением, к которому присваивается. Присвоение типа - это способ, которым программист говорит компилятору: "Я знаю, что такое присвоение может быть рискованным, но верь мне, ведь я - специалист". Конечно, если результат при этом теряет точность так, что программа не функционирует должным образом, - это ответсвенность программиста.

Присвоение типа может быть применено и к объектным (непримитивным) типам. Это типично, например, для случаев, когда используются контейнеры типа Vector. Если вы помещаете объект типа String в Vector, то когда вы его извлекаете, тип, возвращаемый методом elementAt(), будет Object. Для использования извлечённого объекта как String нужно применить приведение типа, как, например, в следующем фрагменте кода:

1. Vector v = new Vector();
2. v.add ("Hello");
3. String s = (String)v.get(0);

В данном примере приведение типа имеет место в третьей строке (конструкция (String)). И хотя компилятор допускает такое приведение типа, во время выполнения программы всё равно проверяется, является объект извлечённый из Vector на самом деле объектом типа String. В будущих выпусках я расскажу о допустимых приведениях типов.

1 комментарий:

Анонимный комментирует...

Я Абрам Александр, бизнесмен, который смог возродить свой умирающий лесозаготовительный бизнес с помощью отправленного Богом кредитора, известного как Бенджамин Ли, Кредитный Консультант. Проживаю в Екатеринбурге Екатеринбург. Вы пытаетесь начать бизнес, погасить свой долг, расширить свой существующий, нуждаетесь в деньгах для покупки расходных материалов. Если у вас возникли проблемы с попыткой получить хорошую кредитную линию, я хочу, чтобы вы знали, что мистер Бенджамин проведет вас до конца. Это правильное место для вас, чтобы решить все ваши финансовые проблемы, потому что я живое свидетельство, и я не могу просто оставить это при себе, когда другие ищут способ быть финансово поднятым .. Я хочу, чтобы вы все связались с этим Богом, посланным кредитором используя детали, как указано в других, чтобы принять участие в этой прекрасной возможности Электронная почта: lfdsloans@outlook.com Или WhatsApp / Text + 1-989-394-3740.