Что полезного можно найти в классах-оболочках?
Числовые классы
В каждом из шести числовых классов-оболочек есть статические методы преобразования строки символов типа String, представляющей число, в соответствующий примитивный
тип: Byte.parseByte(), Double.parseDouble(), Float.parseFloat(), Integer.parseInt(), Long.parseLong(), Short.parseShort ( ). Исходная строка типа String, как всегда в статических методах, служит параметром метода. Эти методы полезны при вводе данных в поля ввода, обработке аргументов командной строки, т. е. всюду, где числа представляются строками символов, состоящими из цифр со знаками плюс или минус и десятичной точкой.
В каждом из этих классов есть статические константы MAX_VALUE и MIN_VALUE, показывающие диапазон числовых значений соответствующих примитивных типов. В классах
Double и Float есть еще константы POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN, о которых шла речь в
Если вы хорошо знаете двоичное представление вещественных чисел, то можете воспользоваться статическими методами floatToIntBits ( ) и doubleToLongBits ( ), представляющими последовательность битов, из которых состоит двоичное представление вещественного числа, в виде целого числа типа int или long соответственно. Исходное вещественное число задается как аргумент метода. Получив целочисленное представление, вы можете изменить отдельные биты получившегося целого числа побитовыми операциями и преобразовать измененное целое число обратно в вещественное значение методами intBitsToFloat ( ) и longBitsToDouble ().
Статическими методами toBinaryString(), toHexString() и toOctalString() классов Integer и Long можно преобразовать целые значения типов int и long, заданные как аргумент метода, в строку символов, показывающую двоичное, шестнадцатеричное или восьмеричное представление числа.
В листинге 4.1 показано применение этих методов, а рис. 4.2 демонстрирует вывод результатов.
Рис. 4.2. Методы числовых классов |
class NumberTest{
public static void main(String[] args){ int i = 0; short sh = 0;
double d = 0;
Integer k1 = Integer.valueOf(55);
Integer k2 = Integer.valueOf(100); Double d1 = Double.valueOf(3.14); try{
i = Integer.parseInt(args[0]); sh = Short.parseShort(args[0]);
d = Double.parseDouble(args[1]); d1 = new Double(args[1]); k1 = new Integer(args[0]); }catch(Exception e){} double x = 1.0 / 0.0; System.out.println("i = " + i); System.out.println("sh = " + sh);
System.out.println("d = " + d);
System.out.println("k1.intValue() = " + k1.intValue()); System.out.println("d1.intValue() = " + d1.intValue());
System.out.println("k1 > k2? " + k1.compareTo(k2));
System.out.println("x = " + x);
System.out.println("x isNaN? " + Double.isNaN(x));
System.out.println("x isInfinite? " + Double.isInfinite(x));
System.out.println("x == Infinity? " + (x == Double.POSITIVE INFINITY)); System.out.println("d = " + Double.doubleToLongBits(d));
System.out.println("i = " + Integer.toBinaryString(i));
System.out.println("i = " + Integer.toHexString(i));
System.out.println("i = " + Integer.toOctalString(i));
}
}
Методы parseInt () и конструкторы классов требуют обработки исключений, поэтому в листинг 4.1 вставлен блок try{}catch(){}. Обработку исключительных ситуаций мы подробно разберем в
Начиная с версии Java SE 5 в JDK входит пакет java.util.concurrent.atomic, в котором, в частности, есть классы AtomicInteger и AtomicLong, обеспечивающие изменение числового значения этих классов на уровне машинных команд. Начальное значение задается конструкторами этих классов. Затем методами addAndGet ( ), getAndAdd ( ), incrementAndGet ( ), getAndnIncrement(), decrementAndGet(), getAndDecrement, getAndSet(), set() можно изменять это значение.
Автоматическая упаковка и распаковка типов
В листинге 4.1 объекты числовых классов создавались статическим методом, в котором указывалось числовое значение объекта:
Integer k1 = Integer.valueOf(55);
Это правильно с точки зрения объектно-ориентированного программирования, но утомительно для программиста. Начиная с пятой версии Java, было решено упростить такую запись. Теперь можно писать
Integer k1 = 55;
как будто k1 — простая числовая переменная примитивного типа. Ничего нового в язык Java такая запись не вносит: компилятор, увидев ее, тут же восстановит применение статического метода. Но она облегчает работу программиста, предоставляя ему привычную форму определения переменной. Как говорят, компилятор делает
int n = k1;