Переменные можно объявлять в любом месте кодового блока, но сделать это следует непременно перед тем, как пользоваться ими. Именно поэтому переменная, определенная в начале метода, доступна для всего кода этого метода. А если объявить переменную в конце блока, то такое объявление окажется, по существу, бесполезным, поскольку переменная станет вообще недоступной для кода.
Следует также иметь в виду, что переменные, созданные в области их действия, удаляются, как только управление в программе передается за пределы этой области. Следовательно, после выхода из области действия переменной содержащееся в ней значение теряется. В частности, переменные, объявленные в теле метода, не хранят значения в промежутках между последовательными вызовами этого метода. Таким образом, срок действия переменной ограничивается областью ее действия.
Если при объявлении переменной осуществляется ее инициализация, то переменная будет повторно инициализироваться при каждом входе в тот блок, в котором она объявлена. Рассмотрим в качестве примера следующую программу:// Демонстрация срока действия переменной,class VarlnitDemo { public static void main(String args[]) { int x; for(x = 0; x < 3; x++) { int у = -1; // переменная у инициализируется при каждом входе в блок System.out.println("у is: 11 + у); // всегда выводится значение -1 у = 100; System.out.println("у is now: " + у); } }}
Ниже приведен результат выполнения данной программы.У is: -1у is now: 100у is: -1у is now: 100у is: : -1у is now: 100
Как видите, на каждом шаге цикла for переменная у инициализируется значением -1. Затем ей присваивается значение 100, но по завершении кодового блока данного цикла оно теряется.
Для правил области действия в Java характерна следующая особенность: имя переменной во вложенном блоке не может совпадать с именем переменной во внешнем блоке. Рассмотрим следующий пример программы. В ней предпринимается попытка объявить две переменные с одним и тем же именем в разных областях действия, и поэтому она не подлежит компиляции./*В этой программе предпринимается попытка объявить переменнуюво внутренней области действия с таким же именем, как и у переменной,определенной во внешней области действия.*** Эта программа не подлежит компиляции. ****/class NestVar { public static void main(String args[]) { int count; // Первое объявление переменной count for (count = 0; count < 10; count = count+1) { System.out.println("This is count: " + count); int count; // Второе объявление переменной count. // Недопустимо, поскольку точно такая же // переменная объявлена раньше!!! for(count = 0; count < 2; count++) System.out.println("This program is in error!"); } }}
Если у вас имеется некоторый опыт программирования на С или C++, то вам, вероятно, известно, что в этих языках отсутствуют какие-либо ограничения на имена переменных, объявляемых во внутренней области действия. Так, в С и C++ объявление переменной count в блоке внешнего цикла for из приведенного выше примера программы вполне допустимо, несмотря на то, что такая же переменная уже объявлена во внешнем блоке. В этом случае переменная во внутреннем блоке скрывает переменную из внешнего блока. Создатели Java решили, что подобное сокрытие имен переменных может привести к программным ошибкам, и поэтому запретили его.Операторы
В Java предусмотрено большое количество операторов. Оператор — это знак, указы вающий компилятору на необходимость выполнения определенного математического или логического действия. Операторы в Java делятся на четыре общие категории: арифметические, поразрядные, логические и отношения. Кроме того, в Java определены некоторые дополнительные операторы для применения в особых случаях. В этой главе будут рассмотрены арифметические и логические операторы, а также операторы отношения присваивания. А о поразрядных и специальных операторах речь пойдет далее в этой книге.Арифметические операторы
В языке Java определены следующие арифметические операторы.ОператорВыполняемое действие+Сложение (а также унарный плюс)-Вычитание (а также унарный минус)*Умножение/Деление%Деление по модулю++Инкремент--Декремент
Операторы +, -, * и / действуют в Java таким же образом, как и в любом другом языке программирования в частности и математике вообще, т.е. выполняют обычные арифметические операции. Их можно применять к числовым данным встроенных типов. Они также применимы к объектам типа char.
Несмотря на то что арифметические операции хорошо всем известны, у них имеются некоторые особенности, требующие специального пояснения. Во-первых, если оператор / применяется к целым числам, остаток от деления отбрасывается. Например, результат целочисленного деления 10/3 равен 3. А для получения остатка от деления следует применить оператор деления по модулю %. В Java он действует таким же образом, как и в других языках программирования. Например, в результате операции 10 % 3 будет получено значение 1. Оператор % применяется не только к целым числам, но и к числам с плавающей точкой. Следовательно, в результате операции 10,0 % 3,0 также будет получено значение 1. Ниже приведен пример программы, демонстрирующий применение оператора %.// Демонстрация оператора %.class ModDemo { public static void main(String args[]) { int iresult, irem; double dresult, drem; iresult = 10 / 3; irem = 10 % 3; dresult = 10.0 / 3.0; drem = 10.0 % 3.0; System.out.println("Result and remainder of 10 / 3: " + iresult + " " + irem); System.out.println("Result and remainder of 10.0 / 3.0: " + dresult + " " + drem); }}
Выполнение этой программы дает следующий результат:Result and remainder of 10 / 3: 3 1Result and remainder of 10.0 / 3.0: 3.3333333333333335 1.0
Как видите, оператор % возвращает остаток от деления как целых чисел, так и чисел с плавающей точкой.Операторы инкремента и декремента
Операторы ++ и —, выполняющие положительное (инкремент) и отрицательное (декремент) приращение значений, были уже представлены в главе 1. Как будет показано ниже, у этих операторов имеется ряд интересных особенностей. Рассмотрим подробнее действия, выполняемые операторами инкремента и декремента.
Оператор инкремента добавляет к своему операнду единицу, а оператор декремента вычитает единицу из операнда. Следовательно, операторх = х + 1;
дает такой же результат, как и операторх++;
а операторх = х - 1;
дает такой же результат, как и оператор—х;
Оба оператора инкремента и декремента могут быть как префиксным (предварять операнд), так и постфиксным (следовать за операндом). Например, операторх = х + 1;
можно переписать так:++х; // префиксная форма
или так:х++; // постфиксная форма
В приведенных выше примерах не имело особого значения, применять ли оператор инкремента в префиксной или постфиксной форме. Но когда операторы инкремента и декремента являются частью более крупного выражения, отличия между этими формами уже имеют значение. Так, если оператор инкремента или декремента предшествует операнду, то сначала выполняется соответствующее приращение, а затем получается значение операнда для последующего его использования в других элементах выражения. А если оператор инкремента или декремента следует за операндом, то сначала получается значение операнда, а затем выполняется инкремент или декремент. Рассмотрим следующие строки кода:х = 10;у = ++х;
После их выполнения значение переменной у будет равно 11. Но если изменить код так, как показано ниже, результат будет другим.х = 10;у = х++;
Теперь значение переменной у равно 10. Но в обоих случаях значение переменной х будет равно 11. Возможность контролировать момент выполнения операции инкремента или декремента дает немало преимуществ при написании программ.Операторы отношения и логические операторы
Операторы отношения отличаются от логических операторов тем, что первые опреде ляют отношения между значениями, а вторые связывают вместе логические значения (true или false), получаемые в результате определения отношений между значениями. Операторы отношения возвращают логическое значение true или false, и поэтому они нередко используются совместно с логическими операторами. По этой причине они и рассматриваются вместе.
Ниже перечислены операторы отношения.ОператорЗначение==Равно|=Неравно>Больше<Меньше>=Больше или равно<=Меньше или равно
Далее перечислены логические операторы.ОператорЗначение&И|ИЛИ^Исключающее ИЛИ||Укороченное ИЛИ&&Укороченное И!НЕ
Результатом выполнения оператора отношения или логического оператора является логическое значение типа boolean.
В Java все объекты могут быть проверены на равенство или неравенство с помощью операторов == и != соответственно. Но операторы <, >, <= и >= могут быть применены только к тем типам данных, для которых определено отношение порядка. Следовательно, все операторы отношения можно применять к данным числовых типов и типа char. А логические значения типа boolean можно проверить только на равенство или неравенство, поскольку истинные (true) и ложные (false) значения не имеют отношения порядка. Например, выражение true > false не имеет смысла в Java.
Операнды логических операторов должны иметь тип boolean, как, впрочем, и результаты выполнения этих операторов. Логические операторы &, |, А и ! выполняют логические операции И, ИЛИ, исключающее ИЛИ и НЕ в соответствии со следующей таблицей истинности.PQP & QP | QP ^ Q!pfalsefalsefalsefalsefalsetruetruefalsefalsetruetruefalsefalsetruefalsetruetruetruetruetruetruetruefalsefalse
Как следует из приведенной выше таблицы, результатом выполнения логической операции исключающее ИЛИ будет истинное значение (true), если один и только один ее операнд имеет логическое значение true.
Приведенный ниже пример программы демонстрирует применение некоторых операторов отношения и логических операторов.// Демонстрация операторов отношения и логических операторов,class RelLogOps { public static void main(String args[]) { int i, j; boolean bl, b2; i = 10; j = 11; if(i < j) System.out.println("i < j"); if(i <= j) System.out.println("i <= j"); if(i != j) System.out.println("i != j"); if(i == j) System.out.println("this won't execute"); if(i >= j) System.out.println("this won't execute"); if(i > j) System.out.println("this won't execute"); bl = true; b2 = false; if(bl & b2) System.out.println("this won't execute"); if(! (bl & b2)) System.out.println("! (bl & b2) is true"); if(bl | b2) System.out.println("bl | b2 is true"); if(bl A b2) System.out.println("bl A b2 is true"); }}
Результат выполнения данной программы выглядит следующим образом:i < ji <= ji != j! (bl & b2) is truebl | b2 is truebl A b2 is trueУкороченные логические операторы
В Java предусмотрены также специальные, укороченные варианты логических операторов И и ИЛИ, предназначенные для получения более эффективного кода. Поясним это на следующих примерах логических операций. Если первый операнд логической операции И имеет ложное значение (false), то ее результат будет иметь ложное значение независимо от значения второго операнда. Если же первый операнд логической операции ИЛИ имеет истинное значение (true), то ее результат будет иметь истинное значение независимо от значения второго операнда. Благодаря тому что значение второго операнда в этих операциях вычислять не нужно, экономится время и повышается эффективность кода.
Укороченная логическая операция И выполняется с помощью оператора 66, а укороченная логическая операция ИЛИ — с помощью оператора | |. Этим укороченным логическим операторам соответствуют обычные логические операторы & и |. Единственное отличие укороченного логического оператора от обычного заключается в том, что второй его операнд вычисляется только по мере необходимости.
В приведенном ниже примере программы демонстрируется применение укороченного логического оператора И. В этой программе с помощью операции деления по модулю определяется следующее: делится ли значение переменной d на значение переменной нацело. Если остаток от деления n/d равен нулю, то п делится на d нацело. Но поскольку данная операция подразумевает деление, то для проверки условия деления на нуль служит укороченный логический оператор И.// Демонстрация укороченных логических операторов,class SCops { public static void main(String args[]) { int n, d, g; n = 10; d = 2; if(d != 0 && (n % d) == 0) System.out.println(d + " is a factor of " + n) ; d = 0; // установить нулевое значение в переменной d // Второй операнд не вычисляется, поскольку значение // переменной d равно нулю. Таким образом, укороченный // логический оператор предотвращает деление на нуль. if (d ! = 0 && (n % d) == 0) // System.out.println(d + " is a factor of " + n) ; /* А теперь те же самые действия выполняются без укороченного логического оператора. На этот раз вычисляются оба операнда, в результате чего возникает ошибка деления на нуль. */ if(d != 0 & (п % d) == 0) System.out.println(d + " is a factor of " + n) ; }}
Для предотвращения возможности деления на нуль в условном операторе if сначала проверяется, равно ли нулю значение переменной d. Если эта проверка дает истинный результат, вычисление второго операнда укороченного логического оператора И не выполняется. Так, если значение переменной d равно 2, вычисляется остаток от деления по модулю. Если же значение переменной d равно нулю, операция деления по модулю пропускается, а следовательно, предотвращается деление на нуль. В конце рассматриваемой здесь программы применяется обычный логический оператор И, в котором вычисляются оба операнда, а это может привести к делению на нуль при выполнении данной программы.
И последнее замечание: в формальной спецификации Java укороченный оператор И называется условным логическим оператором И, а укороченный оператор ИЛИ — условным логическим оператором ИЛИ, но чаще подобные операторы называются укороченными.Оператор присваивания
Оператор присваивания уже не раз применялся в примерах программ, начиная с главы 1. И теперь настало время дать ему формальное определение. Оператор присваивания обозначается одиночным знаком равенства (=). В Java он выполняет те же действия, что и в других языках программирования. Ниже приведена общая форма этого оператора.переменная = выражение
где переменная и выражение должны иметь совместимые типы.
У оператора присваивания имеется одна интересная особенность, о которой вам будет полезно знать: он позволяет создавать цепочку операций присваивания. Рассмотрим, например, следующий фрагмент кода:int х, у, z;x=y=z=100; // присвоить значение 100 переменным х, у и z
В приведенном выше фрагменте кода одно и то же значение 100 задается для переменных х, у и z с помощью единственного оператора присваивания =, получающего всякий раз значение от операнда из правой части выражения. Таким образом, значение 100 присваивается сначала переменной z, затем переменной у и, наконец, переменной х. Такой способ присваивания по цепочке удобен для задания общего значения целой группе переменных.Укороченные операторы присваивания
В Java предусмотрены специальные укороченные операторы присваивания, упрощающие программирование некоторых операций присваивания. Обратимся сначала к простому примеру. Приведенный ниже оператор присваиваниях = х + 10;
можно переписать, используя следующий укороченный оператор присваивания:х += 10;
Пара операторов += указывает компилятору на то, что переменной х должно быть присвоено ее первоначальное значение, увеличенное на 10.
Рассмотрим еще один пример. Операторх = х - 100;
и операторх -= 100;
выполняют одни и те же действия. Оба оператора присваивают переменной х ее первоначальное значение, уменьшенное на 100.
Для многих двоичных операций в Java, т.е. операций, требующих наличия двух операндов, существуют отдельные укороченные операторы присваивания. Общая форма всех этих операторов имеет следующий вид:переменная ор = выражение