Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Классы-обёртки (Wrapper Classes)
Классы-обёртки (Wrapper Classes) — это объектные аналоги примитивных типов данных. Они позволяют использовать примитивные типы как объекты, необходимые для коллекций и обобщений (generics).
Основные классы-обёртки
// Соответствие примитивных типов и их обёрток
primitive wrapper size
byte <-> Byte 8 bit
short <-> Short 16 bit
int <-> Integer 32 bit
long <-> Long 64 bit
float <-> Float 32 bit
double <-> Double 64 bit
char <-> Character 16 bit
boolean <-> Boolean 1 bit
// Все наследуют от Number, кроме Boolean
public abstract class Number {
public abstract int intValue();
public abstract long longValue();
public abstract float floatValue();
public abstract double doubleValue();
}
1. Boxing и Unboxing
// Manual Boxing
int primitive = 42;
Integer boxed = Integer.valueOf(42); // Boxing
Integer boxed2 = new Integer(42); // Deprecated (с Java 9)
// Manual Unboxing
int unboxed = boxed.intValue(); // Unboxing
// Auto-boxing и Auto-unboxing (Java 5+)
Integer autoBoxed = 42; // Автоматический boxing
int autoUnboxed = autoBoxed; // Автоматический unboxing
// В коллекциях
List<Integer> numbers = new ArrayList<>();
numbers.add(100); // Auto-boxing: int -> Integer
int num = numbers.get(0); // Auto-unboxing: Integer -> int
2. Integer
// Константы
int maxValue = Integer.MAX_VALUE; // 2147483647
int minValue = Integer.MIN_VALUE; // -2147483648
int size = Integer.SIZE; // 32 bits
int bytes = Integer.BYTES; // 4
// Преобразование из строки
Integer fromString = Integer.parseInt("42"); // 42
Integer valueOf = Integer.valueOf("42"); // 42
Integer fromHex = Integer.parseInt("2A", 16); // 42
// Преобразование в строку
String str = Integer.toString(42); // "42"
String hex = Integer.toHexString(42); // "2a"
String binary = Integer.toBinaryString(42); // "101010"
// Сравнение
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // true (кэширование для -128..127)
Integer c = 200;
Integer d = 200;
System.out.println(c == d); // false (нет кэширования)
System.out.println(c.equals(d)); // true (правильно сравнивать)
// Битовые операции
int bitCount = Integer.bitCount(42); // 3
int highBit = Integer.highestOneBit(42); // 32
int rotate = Integer.rotateLeft(42, 2);
3. Long
// Для больших чисел
Long bigNumber = 9223372036854775807L; // MAX_VALUE
String hexLong = Long.toHexString(999999999L);
// Парсинг
Long fromString = Long.parseLong("1234567890");
// Битовые операции
long shiftLeft = 42L << 3; // Сдвиг влево
long shiftRight = 42L >> 1; // Сдвиг вправо
4. Double и Float
// Double (64-bit, точнее)
Double d = 3.14159;
Double maxValue = Double.MAX_VALUE; // ~1.8e308
Double minValue = Double.MIN_VALUE; // ~4.9e-324
// Специальные значения
Double infinity = Double.POSITIVE_INFINITY;
Double negInf = Double.NEGATIVE_INFINITY;
Double nan = Double.NaN;
boolean isNaN = Double.isNaN(nan); // true
boolean isInfinite = Double.isInfinite(infinity); // true
boolean isFinite = Double.isFinite(3.14); // true
// Float (32-bit, менее точный)
Float f = 3.14f;
Float floatMax = Float.MAX_VALUE; // ~3.4e38
// Сравнение
Double a = 0.1 + 0.2;
Double b = 0.3;
System.out.println(a == b); // false (ошибка floating point)
System.out.println(Math.abs(a - b) < 1e-10); // true
5. Character
// Основные методы
char c = 'A';
boolean isLetter = Character.isLetter(c); // true
boolean isDigit = Character.isDigit('5'); // true
boolean isWhitespace = Character.isWhitespace(' '); // true
boolean isUpperCase = Character.isUpperCase(c); // true
boolean isLowerCase = Character.isLowerCase('a'); // true
// Преобразование регистра
char upper = Character.toUpperCase('a'); // 'A'
char lower = Character.toLowerCase('A'); // 'a'
// Код символа
int charCode = Character.getNumericValue('5'); // 5
int codePoint = (int) c; // 65
// Работа с Unicode
int codePointCount = Character.codePointCount("Hello", 0, 5);
char[] chars = Character.toChars(0x1F600); // Emoji
6. Boolean
// Создание
Boolean bool1 = true;
Boolean bool2 = Boolean.TRUE; // Предпочтительнее
Boolean bool3 = Boolean.valueOf("true");
// Парсинг
Boolean fromString = Boolean.parseBoolean("true"); // true
Boolean valueOf = Boolean.valueOf("true"); // true
// Сравнение
Boolean a = true;
Boolean b = true;
System.out.println(a == b); // true (только 2 объекта: TRUE, FALSE)
System.out.println(a.equals(b)); // true
// Логические операции
Boolean result = a && b; // Boolean (auto-unbox при && )
Boolean orResult = a.logicalOr(b); // true
Boolean andResult = a.logicalAnd(b); // true
Boolean xorResult = a.logicalXor(false); // true
Примеры использования в коллекциях
// ❌ Невозможно с примитивными типами
// List<int> numbers = new ArrayList<>(); // Compilation error
// ✅ Нужны wrapper классы
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
// Итерация
for (Integer num : numbers) {
int value = num; // Auto-unboxing
System.out.println(value);
}
// Map с обёртками
Map<String, Integer> ages = new HashMap<>();
ages.put("Alice", 25);
ages.put("Bob", 30);
// Set уникальных значений
Set<Double> uniqueScores = new HashSet<>();
uniqueScores.add(9.5);
uniqueScores.add(8.5);
Кэширование и оптимизация
// Integer и Long кэшируют значения от -128 до 127
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // true (из кэша)
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // false (не из кэша, разные объекты)
System.out.println(c.equals(d)); // true (правильное сравнение)
// Поэтому ВСЕГДА используй equals(), не ==
Null-pointer risks
// Опасность при unboxing
Integer value = null;
int primitive = value; // NullPointerException!
// Безопасно
Integer value = Integer.valueOf(10);
int primitive = value; // OK
// Проверка перед unboxing
Integer maybeNull = getNullableInteger();
int result = maybeNull != null ? maybeNull : 0; // Safe
// Или с Optional
Optional<Integer> opt = Optional.ofNullable(maybeNull);
int result = opt.orElse(0);
Performance considerations
// Wrapper классы требуют больше памяти
byte primitive = 42; // 1 byte
Byte boxed = Byte.valueOf(42); // Объект (заголовок + данные)
// Auto-boxing имеет overhead
Integer sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i; // Auto-boxing при каждой операции!
}
// Лучше
int sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i; // Никакого boxing, быстро
}
Таблица методов (Integer как пример)
| Метод | Описание |
|---|---|
| parseInt() | Преобразование строки в примитив |
| valueOf() | Преобразование в wrapper |
| toString() | Преобразование в строку |
| compare() | Сравнение двух значений |
| equals() | Проверка на равенство |
| MAX_VALUE, MIN_VALUE | Граничные значения |
Best Practices
- Используй wrapper классы для коллекций и generics
- Сравнивай wrapper классы через equals(), не ==
- Избегай ненужного boxing в циклах
- Проверяй на null перед unboxing
- Используй Optional вместо null wrapper классов
- Для денег используй BigDecimal, не Double
Wrapper классы — необходимый инструмент для работы с объектно-ориентированным кодом Java, но нужно понимать их особенности производительности и null-safety.