Классы обертки в Java (оболочки типов) - Вопросы
Всего: 3 вопросов
1. Что такое классы-обертки (wrapper classes) в Java и зачем они нужны?
Что такое классы-обертки (wrapper classes) в Java и зачем они нужны?
Классы-обертки из пакета java.lang хранят одно значение примитивного типа в виде объекта. У каждого из восьми примитивов есть своя обертка: Byte, Short, Integer, Long, Float, Double, Character, Boolean. Имя совпадает с примитивом с заглавной буквы, исключения — Integer (int) и Character (char).
Обертки нужны, чтобы:
- хранить числа в коллекциях и generics (
List<Integer>—List<int>не компилируется); - обозначать отсутствие значения через
null; - преобразовывать строки в числа и обратно (
Integer.parseInt(),Integer.toString()); - пользоваться константами и утилитами (
Integer.MAX_VALUE,Character.isDigit(),Double.isNaN()).
Объекты оберток неизменяемы (immutable). Числовые обертки наследуют абстрактный класс Number, а Character и Boolean — нет.
2. Чем Integer.valueOf(String) отличается от Integer.parseInt(String)? Что произойдет, если строка не является числом?
Чем Integer.valueOf(String) отличается от Integer.parseInt(String)? Что произойдет, если строка не является числом?
Оба метода разбирают строку, различается тип результата: Integer.valueOf("42") возвращает объект Integer, а Integer.parseInt("42") — примитив int. Внутри valueOf(String) вызывает parseInt() и упаковывает результат.
int count = Integer.parseInt("42"); // примитив, без объекта
Integer boxed = Integer.valueOf("42"); // объект Integer
int bin = Integer.parseInt("101011", 2); // 43, с указанием основания
Если нужен int — используйте parseInt(), если объект (для коллекции или nullable-поля) — valueOf().
Для некорректной строки оба метода бросают непроверяемое NumberFormatException: например, для " 42" (пробелы не обрезаются), "4.2", "abc" и даже null. Исключение — Boolean.parseBoolean()/Boolean.valueOf(): они никогда не бросают исключение и возвращают false для любой строки, кроме "true" в любом регистре.
3. Почему конструкторы вида new Integer(42) считаются устаревшими и чем их заменить?
Почему конструкторы вида new Integer(42) считаются устаревшими и чем их заменить?
Конструкторы всех классов-оберток (new Integer(42), new Integer("42"), new Boolean("true") и т.д.) объявлены устаревшими в Java 9, а начиная с Java 16 помечены @Deprecated(forRemoval = true) (JEP 390) — их могут удалить в будущих версиях, компилятор выдает предупреждение.
Главная причина: конструктор всегда создает новый объект, а valueOf() может вернуть готовый объект из кэша, что экономит память. Кроме того, обертки рассматриваются как value-based классы, для которых идентичность объекта не должна иметь значения.
Integer i1 = 42; // автоупаковка
Integer i2 = Integer.valueOf("42"); // из строки
Boolean b1 = Boolean.valueOf("true");
Character c1 = Character.valueOf('c');