Эккель Брюс
Шрифт:
В Java разрешается приводить любой простейший тип данных к любому другому простейшему типу, но это не относится к типу boolean, который вообще не подлежит приведению. Классы также не поддерживают произвольное приведение. Чтобы преобразовать один класс в другой, требуются специальные методы. (Как будет показано позднее, объекты можно преобразовывать в рамках семейства типов; объект Дуб можно преобразовать в Дерево и наоборот, но не к постороннему типу вроде Камня.)
Округление и усечение
При выполнении сужающих преобразований необходимо обращать внимание на усечение и округление данных. Например, как должен действовать компилятор Java при преобразовании вещественного числа в целое? Скажем, если значение 29,7 приводится к типу int, что получится — 29 или 30? Ответ на этот вопрос может дать следующий пример:
//: operators/CastingNumbers.java // Что происходит при приведении типов // float или double к целочисленным значениям? import static net.mindview.util.Print *;
public class CastingNumbers {
public static void main(String[] args) { double above = 0.7, below = 0.4; float fabove = 0.7f, fbelow = 0 4f; print("(int)above: " + (int)above); print("(int)below: " + (int)below), printC(int)fabove- " + (int)fabove); print("(int)fbelow. " + (int)fbelow),
}
} /* Output: (int)above: 0 (int)below. 0 (int)fabove: 0 (int)fbelow: 0 *///:-
Отсюда и ответ на наш вопрос — приведение от типов с повышенной точностью double и float к целочисленным значениям всегда осуществляется с усечением целой части. Если вы предпочитаете, чтобы результат округлялся, используйте метод round из java.lang.Math. Так как этот метод является частью java.lang, дополнительное импортирование не потребуется.
Повышение
Вы можете обнаружить, что при проведении любых математических и поразрядных операций примитивные типы данных, меньшие int (то есть char, byte и short), приводятся к типу int перед проведением операций, и получаемый результат имеет тип int. Поэтому, если вам снова понадобится присвоить его меньшему типу, придется использовать приведение. (И тогда возможна потеря информации.) В основном самый емкий тип данных, присутствующий в выражении, и определяет величину результата этого выражения; так, при перемножении float и double результатом станет double, а при сложении long и int вы получите в результате long.
В Java отсутствует sizeof
В С и С++ оператор sizeof выдает количество байтов, выделенных для хранения данных. Главная причина для использования sizeof — переносимость программы. Различным типам данных может отводиться различное количество памяти на разных компьютерах, поэтому для программиста важно определить размер этих типов перед проведением операций, зависящих от этих величин. Например, один компьютер выделяет под целые числа 32 бита, а другой — всего лишь 16 бит. В результате на первой машине программа может хранить в целочисленном представлении числа из большего диапазона. Конечно, аппаратная совместимость создает немало хлодот для программистов на С и С++.
В Java оператор sizeof не нужен, так как все типы данных имеют одинаковые размеры на всех машинах. Вам не нужно заботиться о переносимости на низком уровне — она встроена в язык.
Сводка операторов
Следующий пример показывает, какие примитивные типы данных используются с теми или иными операторами. Вообще-то это один и тот же пример, повторенный много раз, но для разных типов данных. Файл должен компилироваться без ошибок, поскольку все строки, содержащие неверные операции, предварены символами //!.
// operators/AHOps java
// Проверяет все операторы со всеми
// примитивными типами данных, чтобы показать,
// какие операции допускаются компилятором Java
public class AT 1 Ops {
// для получения результатов тестов типа boolean: void f(boolean b) {} void boolTest(boolean x, boolean y) { // Арифметические операции-//' x = x * у; //! x = x / у;
//! х = х % у; III х = х + у; III х = х - у; III х++; //! х--; //! х = +у; //! х = -у;
// Операции сравнения и логические операции:
III f(х > у),
//! f(х >= у);
III f(х < у).
Ill f(х <= у);
f(x == у),
f(х != у);
f(!y);
х = х && у: х = х || у.
// Поразрядные операторы:
III х =
X = X =
II II II // // // // // // // // // X &= у: х А= у: х |= у.
// Приведение-