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

От какого класса наследуются Integer, Long и Double?

2.0 Middle🔥 251 комментариев
#Docker, Kubernetes и DevOps#REST API и микросервисы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Иерархия классов Integer, Long и Double

Краткий ответ

Integer, Long и Double наследуются от класса Number, который в свою очередь наследуется от Object. Это фундаментальная иерархия в Java для работы с числовыми типами.

Иерархия наследования

Object
  └── Number (abstract)
        ├── Integer
        ├── Long
        ├── Double
        ├── Float
        ├── Short
        ├── Byte
        └── BigDecimal
        └── BigInteger

Определение класса Number

Number - это абстрактный класс, определяющий общий интерфейс для числовых обёрток:

public abstract class Number extends Object implements Serializable {
    // Методы преобразования
    public abstract int intValue();
    public abstract long longValue();
    public abstract float floatValue();
    public abstract double doubleValue();
    
    // Удобные методы
    public byte byteValue() {
        return (byte) intValue();
    }
    
    public short shortValue() {
        return (short) intValue();
    }
}

Наследование Integer

public final class Integer extends Number implements Comparable<Integer> {
    private final int value;
    
    public Integer(int value) {
        this.value = value;
    }
    
    @Override
    public int intValue() {
        return value;
    }
    
    @Override
    public long longValue() {
        return (long) value;
    }
    
    @Override
    public double doubleValue() {
        return (double) value;
    }
    
    // ... остальные методы
}

Практическое использование

1. Полиморфизм через Number

// Функция работает с любым числовым типом
public double convertToDouble(Number number) {
    return number.doubleValue();
}

// Вызовы
Integer intVal = 42;
Long longVal = 1000L;
Double doubleVal = 3.14;
Float floatVal = 2.71f;

convertToDouble(intVal);      // 42.0
convertToDouble(longVal);     // 1000.0
convertToDouble(doubleVal);   // 3.14
convertToDouble(floatVal);    // 2.71

2. Преобразование между типами

Integer integer = 100;

// Через методы Number
int intVal = integer.intValue();      // 100
long longVal = integer.longValue();   // 100L
double doubleVal = integer.doubleValue(); // 100.0
float floatVal = integer.floatValue(); // 100.0f

// Через Number интерфейс
Number num = integer;
long result = num.longValue();        // 100L

3. Работа с коллекциями

// Коллекция любых числовых типов
List<? extends Number> numbers = Arrays.asList(
    10,           // Integer
    20L,          // Long
    30.5,         // Double
    40f           // Float
);

// Получение средневзвешенного значения
public double calculateAverage(List<? extends Number> numbers) {
    return numbers.stream()
        .mapToDouble(Number::doubleValue)
        .average()
        .orElse(0.0);
}

double avg = calculateAverage(numbers); // (10 + 20 + 30.5 + 40) / 4

Почему Number нужен?

ПреимуществоОписание
Единый интерфейсВсе числовые типы имеют одинаковые методы
ПолиморфизмФункции работают с любым числовым типом
Type ErasureДля generics List<Number> работает со всеми числами
Упрощение кодаНе нужны перегрузки для каждого типа

Важные особенности

1. Immutability

Все наследники Number - это immutable классы:

public final class Integer extends Number {
    private final int value;  // ← final!
    
    // Нельзя изменить значение после создания
}

2. Caching

Integer и Long кэшируют малые значения:

Integer a = 127;
Integer b = 127;
System.out.println(a == b);  // true (из кэша)

Integer c = 128;
Integer d = 128;
System.out.println(c == d);  // false (разные объекты)

// Integer кэширует [-128, 127]
Integer.valueOf(127);  // из кэша
Integer.valueOf(128);  // новый объект

3. Autoboxing

// Automatic boxing/unboxing
Integer integer = 42;        // Integer.valueOf(42)
int primitive = integer;      // integer.intValue()

// Хранение в List
List<Integer> numbers = new ArrayList<>();
numbers.add(100);            // autoboxing
int value = numbers.get(0);  // unboxing

BigDecimal и BigInteger

Для больших и точных расчётов есть специальные классы:

// BigInteger - для очень больших целых чисел
BigInteger large = new BigInteger("123456789012345678901234567890");

// BigDecimal - для точных десятичных расчётов
BigDecimal price = new BigDecimal("19.99");
BigDecimal tax = price.multiply(new BigDecimal("0.1"));

// Оба наследуются от Number
Number bigNum = large;
Number decimalNum = price;

Ловушки

// ❌ Не полагайся на == для обёрток
Integer a = 200;
Integer b = 200;
System.out.println(a == b);  // false! (разные объекты)
System.out.println(a.equals(b));  // true (правильно)

// ✅ Используй equals()
if (a.equals(b)) { ... }

// ❌ NullPointerException при unboxing
Integer nullInt = null;
int primitive = nullInt;  // NPE!

// ✅ Проверяй на null
if (nullInt != null) {
    int value = nullInt;
}

Вывод

Number - это фундаментальный абстрактный класс, который объединяет все числовые обёртки. Понимание этой иерархии критично для работы с коллекциями, generics и полиморфизмом в Java.