22
Н
а нижнем уровне операции с данными в Java осуществляются посредством операторов.
Язык Java создавался на основе С++, поэтому большинство этих операторов и конструкций знакомы программистам на С и С++. Также в Java были добав¬лены некоторые улучшения и упрощения.
Если вы .знакомы с синтаксисом С или С++, бегло просмотрите эту и сле¬дующую главу, останавливаясь на тех местах, в которых Java отличается от этих языков. Если чтение дается вам с трудом, попробуйте обратиться к мультиме¬дийному семинару Thinking in С, свободно загружаемому с сайтаwww.Mind- View.net. Он содержит аудиолекции, слайды, упражнения и решения, специаль¬но разработанные для быстрого ознакомления с синтаксисом С, необходимым для успешного овладения языком Java.
Простые команды печати
В предыдущей главе была представлена команда печати Java
System.out.println("Какая длинная команда...");
Вероятно, вы заметили, что команда не только получается слишком длин¬ной, но и плохо читается. Во многих языках до и после Java используется более простой подход к выполнению столь распространенной операции.
В главе 6 представлена концепция статического импорта, появившаяся в Java SE5, а также крошечная библиотека, упрощающая написание команд пе¬чати. Тем не менее для использования библиотеки не обязательно знать все подробности. Программу из предыдущей главы можно переписать в следующем виде:
// operators/HelloDate java import java util *.
import static net mindview util Print.*,
public class HelloDate {
public static void main(String[] args) { print("Привет, сегодня- "); print(new DateO),
}
} /* Output- (55% match)
Привет, сегодня
Wed Oct 05 14-39 36 MDT 2005
*///:-
Результат смотрится гораздо приятнее. Обратите внимание на ключевое слово static во второй команде import.
Чтобы использовать эту библиотеку, необходимо загрузить архив с приме¬рами кода. Распакуйте его и включите корневой каталог дерева в переменную окружения CLASSPATH вашего компьютера. Хотя использование net.mindview. util. Print упрощает программный код, оно оправданно не везде. Если программа содержит небольшое количество команд печати, я отказываюсь от import и за¬писываю полный вызов System.out.println().
Операторы Java
Оператор получает один или несколько аргументов и создает на их основе но¬вое значение. Форма передачи аргументов несколько иная, чем при вызове ме¬тода, но эффект тот же самый. Сложение (+), вычитание и унарный минус (-), умножение (*), деление (/) и присвоение (=) работают одинаково фактически во всех языках программирования.
Все операторы работают с операндами и выдают какой-то результат. Вдоба¬вок некоторые операторы могут изменить значение операнда. Это называется побочным эффектом. Как правило, операторы, изменяющие значение своих операндов, используются именно ради побочного эффекта, но вы должны пом¬нить, что полученное значение может быть использовано в программе и обыч¬ным образом, независимо от побочных эффектов.
Почти все операторы работают только с примитивами. Исключениями явля¬ются =, = = и !=, которые могут быть применены к объектам (и создают немало затруднений). Кроме того, класс String поддерживает операции + и +=.
Приоритет
Приоритет операций определяет порядок вычисления выражений с нескольки¬ми операторами. В Java существуют конкретные правила для определения оче¬редности вычислений. Легче всего запомнить, что деление и умножение выпол¬няются раньше сложения и вычитания. Программисты часто забывают правила предшествования, поэтому для явного задания порядка вычислений следует ис¬пользовать круглые скобки. Например, взгляните на команды (1) и (2):
// operators/Precedence java
public class Precedence {
public static void main(String[] args) {
int x = 1, у = 2, z = 3; // (1)
int b = x + (y - 2)/(2 + z), // (2) System out.printlnC'a = " + a + " b = " + b;
}
} /* Output a = 5 b = 1 *///.-
Команды похожи друг на друга, но из результатов хорошо видно, что они имеют разный смысл в зависимости от присутствия круглых скобок.
Обратите внимание на оператор + в команде System.out.println. В данном кон¬тексте + означает конкатенацию строк, а не суммирование. Когда компилятор встречает объект String, за которым следует + и объект, отличный от String, он пытается преобразовать последний объект в String. Как видно из выходных дан¬ных, для а и b тип int был успешно преобразован в String.
Присвоение
Присвоение выполняется оператором =. Трактуется он так: «взять значение из правой части выражения (часто называемое просто значением) и скопировать его в левую часть (часто называемую именующим выражением)». Значением может быть любая константа, переменная или выражение, но в качестве име¬нующего выражения обязательно должна использоваться именованная пере¬менная (то есть для хранения значения должна выделяться физическая па¬мять). Например, вы можете присвоить постоянное значение переменной:
а = 4
но нельзя присвоить что-либо константе — она не может использоваться в каче¬стве именующего выражения (например, запись 4 = а недопустима).
Для примитивов присвоение выполняется тривиально. Так как примитив¬ный тип хранит данные, а не ссылку на объект, то присвоение сводится к про¬стому копированию данных из одного места в другое. Например, если команда а = b выполняется для примитивных типов, то содержимое b просто копируется в а. Естественно, последующие изменения а никак не отражаются на Ь. Для про¬граммиста именно такое поведение выглядит наиболее логично.
При присвоении объектов все меняется. При выполнении операций с объек¬том вы в действительности работаете со ссылкой, поэтому присвоение «одного объекта другому» на самом деле означает копирование ссылки из одного места в другое. Это значит, что при выполнении команды с = d для объектов в конеч¬ном итоге end указывают на один объект, которому изначально соответствова¬ла только ссылка d. Сказанное демонстрирует следующий пример:
//: operators/Assignment java // Присвоение объектов имеет ряд хитростей import static net.mindview.util Print.*,
class Tank {
int level,
}
public class Assignment {
public static void main(String[] args) { Tank tl = new TankO. Tank t2 = new TankO, tl level = 9; t2 level = 47,