Результат выполнения программы ShowBitsDemo выгладит следующим образом: 123 in binary: 01111011 87987 in binary: 00000000 00000001 01010111 10110011 237658768 in binary: 00000000 00000000 00000000 00000000 00001110 00101010 01100010 10010000 Low order 8 bits of 87987 in binary: 10110011Оператор ?
Оператор ? — один из самых удобных в Java. Он часто используется вместо операторов if-else в следующей общей форме:if (условие) var = выражение_1;else var = выражение_2;
где значение, присваиваемое переменной var, определяет условие, управляющее выполнением оператора if. Оператор ? называется тернарным, поскольку он обрабатывает три операнда. Этот оператор записывается в следующей общей форме:выражение_ 1 ? выражение_2 : выражение_3;
где выражение_1 должно быть логическим, т.е. возвращать тип boolean, а выражение_2 и выражение_3, разделяемые двоеточием, могут быть любого типа, за исключением void. Но типы второго и третьего выражений должны непременно совпадать.
Значение выражения ? определяется следующим образом. Сначала вычисляется выражение_1. Если оно дает логическое значение true, то вычисляется выражение_2, а его значение становится результирующим для всего выражения ?. Если же выражение_1 дает логическое значение false, то вычисляется выражение_3, а его значение стано вится результирующим для всего выражения ?. Рассмотрим пример, в котором сначала вычисляется абсолютное значение переменной val, а затем оно присваивается переменной absval.absval = val < 0 ? -val : val; // получить абсолютное значение переменной val
В данном примере переменной absval присваивается значение переменной val, если это значение больше или равно нулю. А если значение переменной val отрицательное, то переменной absval присваивается значение val со знаком “минус”, что в итоге дает положительную величину. Код, выполняющий ту же самую функцию, но с помощью логической конструкции if-else, будет выглядеть следующим образом:if(val < 0) absval = -val;else absval = val;
Рассмотрим еще один пример применения оператора ?. В этом примере программы выполняется деление двух чисел, но не допускается деление на нуль:// Предотвращение деления на нуль с помощью оператора ?.class NoZeroDiv { public static void main(String args[]) { int result; for(int i = -5; i < 6; i++) { // Деление на нуль предотвращается. result = i != 0 ? 100 / i : 0; if(i != 0) System.out.println("100 / " + i + " is " + result); } }}
Ниже приведен результат выполнения данной программы.100 / -5 is -20100 / -4 is -25100 / -3 is -33100 / -2 is -50100 / -1 is -100100 / 1 is 100100 / 2 is 50100 / 3 is 33100 / 4 is 25100 / 5 is 20
Обратите особое внимание на следующую строку кода:result = i != 0 ? 100 / i : 0;
где переменной result присваивается результат деления числа 100 на значение переменной i. Но деление выполняется только в том случае, если значение переменной i не равно нулю. В противном случае переменной result присваивается нулевое значение.
Значение, возвращаемое оператором ?, не обязательно присваивать переменной. Его можно, например, использовать в качестве параметра при вызове метода. Если же все три выражения оператора ? имеют тип boolean, то сам оператор ? может быть использован в качестве условия для выполнения цикла или оператора if. Ниже приведена немного видоизмененная версия предыдущего примера программы. Ее выполнение дает такой же результат, как и прежде.// Предотвращение деления на нуль с помощью оператора ?.class NoZeroDiv2 { public static void main(String args[]) { for(int i = -5; i < 6; i++) if(i != 0 ? true : false) System.out.println("100 / " + i + " is " + 100 / i); }}
Обратите внимание на выражение, определяющее условие выполнения оператора if. Если значение переменной i равно нулю, то оператор ? возвращает логическое значение false, что предотвращает деление на нуль, и результат не отображается. В противном случае осуществляется обычное деление.Упражнение для самопроверки по материалу главы 5
Покажите два способа объявления одномерного массива, состоящего из 12 элементов типа double.
Покажите, как инициализировать одномерный массив целочисленными значениями от 1 до 5.
Напишите программу, в которой массив используется для нахождения среднего арифметического десяти значений типа double. Используйте любые десять чисел.
Измените программу, написанную в примере для опробования 5.1, таким образом, чтобы она сортировала массив символьных строк. Продемонстрируйте ее работоспособность.
В чем отличие методов indexOf () и lastlndexOf () из класса String?
Все символьные строки являются объектами типа String. Покажите, как вызываются методы length () и charAt () для строкового литерала "I like Java" (Мне нравится Java).
Расширьте класс Encode таким образом, чтобы в качестве ключа шифрования использовалась строка из восьми символов.
Можно ли применять поразрядные операторы к значениям типа double?
Перепишите приведенную ниже последовательность операторов, воспользовавшись оператором ?.if (х < 0) у = 10;else у = 20;
В приведенном ниже фрагменте кода содержится знак &. Какой оператор он обозначает: поразрядный или логический? Обоснуйте свой ответ.boolean а, Ь;// ...if (а & Ь) ...
Является ли ошибкой превышение верхней границы массива? Является ли ошибкой использование отрицательных значений для доступа к элементам массива?
Как обозначается оператор сдвига вправо без знака?
Перепишите рассмотренный ранее в этой главе класс MinMax таким образом, чтобы в нем использовалась разновидность for-each цикла for.
В примере для опробования 5.1 была реализована пузырьковая сортировка. Можно ли в программе из этого примера заменить обычный цикл for его разновидностью for-each? Если нельзя, то почему?
Можно ли управлять оператором switch с помощью объектов типа String?
Глава 6 Дополнительные сведения о методах и классах
Основные навыки и понятия
Управление доступом к членам классов
Передача объектов при вызове методов
Возврат объектов из методов
Перегрузка методов
Перегрузка конструкторов
Применение рекурсии
Использование ключевого слова static
Применение внутренних классов
Использование аргументов переменной длины
В этой главе возобновляется рассмотрение классов и методов. Сначала будет показано, каким образом контролируется доступ к членам класса, а затем рассмотрены особенности передачи и возврата объектов из методов, перегрузки методов, использования рекурсии и ключевого слова static. Кроме того, в этой главе будут представлены вложенные классы и методы с аргументами переменной длины.Управление доступом к членам класса
Поддержка свойства инкапсуляции в классе дает два главных преимущества. Во-первых, класс связывает данные с кодом. Это преимущество использовалось в предыдущих примерах программ, начиная с главы 4. И во-вторых, класс предоставляет средства для управления доступом к его членам. Именно эта, вторая преимущественная особенность и будет рассмотрена ниже.
В языке Java, по существу, имеются два типа членов класса: открытые (public) и закрытые (private), хотя в действительности дело обстоит немного сложнее. Доступ к открытому члену свободно осуществляется из кода, определенного за пределами класса. Именно этот тип члена класса использовался в рассматривавшихся до сих пор примерах программ. А закрытый член класса доступен только методам, определенным в самом классе. С помощью закрытых членов и организуется управление доступом.
Ограничение доступа к членам класса является основополагающей частью объектно-ориентированного программирования, поскольку оно позволяет исключить неверное использование объекта. Разрешая доступ к закрытым данным только с помощью строго определенного ряда методов, можно предупредить присваивание неверных значений этим данным, выполняя, например, проверку диапазона представления чисел. Для закрытого члена класса нельзя задать значение непосредственно в коде за пределами класса. Но в то же время можно полностью управлять тем, как и когда данные используются в объекте. Следовательно, правильно реализованный класс образует некий “черный ящик”, которым можно пользоваться, но внутренний механизм «его действия закрыт для вмешательства извне.