← Назад к вопросам

Какие знаешь классы-обёртки?

2.0 Middle🔥 111 комментариев
#Базы данных и SQL

Комментарии (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

  1. Используй wrapper классы для коллекций и generics
  2. Сравнивай wrapper классы через equals(), не ==
  3. Избегай ненужного boxing в циклах
  4. Проверяй на null перед unboxing
  5. Используй Optional вместо null wrapper классов
  6. Для денег используй BigDecimal, не Double

Wrapper классы — необходимый инструмент для работы с объектно-ориентированным кодом Java, но нужно понимать их особенности производительности и null-safety.

Какие знаешь классы-обёртки? | PrepBro