Эккель Брюс
Шрифт:
Заметьте, что значение boolean автоматически переделывается в подходящее строковое представление там, где предполагается использование строкового типа String.
Определение int в этой программе можно заменить любым примитивным типом, за исключением boolean. Впрочем, будьте осторожны с вещественными числами, поскольку их сравнение проводится с крайне высокой точностью. Число, хотя бы чуть-чуть отличающееся от другого, уже считается неравным ему. Число, на тысячную долю большее нуля, уже не является нулем.
Ускоренное вычисление
При работе с логическими операторами можно столкнуться с феноменом, называемым «ускоренным вычислением». Это значит, что выражение вычисляется только до тех пор, пока не станет очевидно, что оно принимает значение «истина» или «ложь». В результате, некоторые части логического выражения могут быть проигнорированы в процессе сравнения. Следующий пример демонстрирует ускоренное вычисление:
//. operators/ShortCircuit.java // Демонстрация ускоренного вычисления // при использовании логических операторов, import static net mindview util Print *;
public class ShortCircuit {
static boolean testl(int val) {
print ("testlC + val + ")"); print("результат- " + (val < 1)); return val <1,
}
static boolean test2(int val) {
print("test2(" + val + ")"); print("результат- " + (val < 2)); return val <2,
}
static boolean test3(int val) {
pnnt("test3(" + val + ")"); print("результат: " + (val < 3)). return val <3;
}
public static void main(String[] args) {
boolean b = testl(O) && test2(2) && test3(2); print ("выражение: " + b);
}
} /* Output: testl(O) результат: true test2(2)
результат: false выражение: false *///:-
Каждый из методов test проводит сравнение своего аргумента и возвращает либо true, либо false. Также они выводят информацию о факте своего вызова. Эти методы используются в выражении
testl(O) && test2(2) && test3(2)
Естественно было бы ожидать, что все три метода должны выполняться, но результат программы показывает другое. Первый метод возвращает результат true, поэтому вычисление выражения продолжается. Однако второй метод выдает результат false. Так как это автоматически означает, что все выражение будет равно false, зачем продолжать вычисления? Только лишняя трата времени. Именно это и стало причиной введения в язык ускоренного вычисления; отказ от лишних вычислений обеспечивает потенциальный выигрыш в производительности.
Литералы
Обычно, когда вы записываете в программе какое-либо значение, компилятор точно знает, к какому типу оно относится. Однако в некоторых ситуациях однозначно определить тип не удается. В таких случаях следует помочь компилятору определить точный тип, добавив дополнительную информацию в виде определенных символьных обозначений, связанных с типами данных. Эти обозначения используются в следующей программе:
//: operators/Literals.java
import static net.mindview.util.Print.*:
public class Literals {
public static void main(String[] args) {
int il = 0x2f; // Шестнадцатеричное (нижний регистр)
printC'ii: " + Integer.toBinaryString(il));
int i2 = 0X2F; // Шестнадцатеричное (верхний регистр)
print("i2: " + Integer.toBinaryString(i2));
int i3 = 0177: // Восьмеричное (начинается с нуля)
print("i3: " + Integer.toBinaryString(i3)):
char с = Oxffff; // макс, шестнадцатеричное знач. char
printC'c: " + Integer.toBinaryString(c));
byte b = 0x7f. // макс шестнадцатеричное знач. byte
printC'b " + Integer toBinaryString(b));
short s = 0x7fff. // макс шестнадцатеричное знач. short
printC's " + Integer.toBinaryString(s));
long nl = 200L; // Суффикс, обозначающий long
long n2 = 2001, // Суффикс, обозначающий long (можно запутаться)
long n3 = 200,
float fl = 1,
float f2 = IF; // Суффикс, обозначающий float float f3 = If, // Суффикс, обозначающий float double dl = Id, // Суффикс, обозначающий double double d2 = ID; // Суффикс, обозначающий double
}
} /* Output-il 101111 12 101111 13: 1111111 c: 1111111111111111 b: 1111111 s- 111111111111111 *///:-
Последний символ обозначает тип записанного литерала. Прописная или строчная буква L определяет тип long (впрочем, строчная I может создать проблемы, потому что она похожа на цифру 1); прописная или строчная F соответствует типу float, а заглавная или строчная D подразумевает тип double.
Шестнадцатеричное представление (основание 16) работает со всеми встроенными типами данных и обозначается префиксом Ох или ОХ с последующим числовым значением из цифр 0-9 и букв a-f, прописных или строчных. Если при определении переменной задается значение, превосходящее максимально для нее возможное (независимо от числовой формы), компилятор сообщит вам об ошибке. В программе указаны максимальные значения для типов char, byte и short. При выходе за эти границы компилятор автоматически сделает значение типом int и сообщит вам, что для присвоения понадобится сужающее приведение.