Integer.valueOf: примеры (JAVA)

Справка по Integer.valueOf
Раздел: Упаковка/распаковка (авто)
Integer.valueOf(int i): Integer

Общее описание и сигнатуры

Метод Integer.valueOf в Java - статический фабричный метод класса java.lang.Integer, возвращающий объект-обертку Integer. Используется при необходимости получить объект Integer из примитивного значения или строкового представления числа. Метод перегружен и имеет основные сигнатуры:

  • public static Integer valueOf(int i) - возвращает объект Integer, представляющий значение i. Реализация обычно использует кэширование для небольших значений.
  • public static Integer valueOf(String s) - парсит десятичную строку s и возвращает соответствующий объект Integer; при неверном формате выбрасывается NumberFormatException.
  • public static Integer valueOf(String s, int radix) - парсит строку s в системе счисления radix (обычно от 2 до 36) и возвращает объект Integer; при недопустимом radix или неверной строке выбрасывается NumberFormatException.

Возвращаемое значение - объект типа Integer. Для valueOf(int) реализация может вернуть кэшированный экземпляр (часто для диапазона от -128 до 127) вместо нового объекта. Для строковых перегрузок сначала выполняется разбор в примитивный int, затем производится упаковка (boxing) в Integer и возможное применение кэша.

Типичные исключения и поведение при граничных случаях:

  • При передаче null в valueOf(String) будет выброшено NumberFormatException (вызванное внутренним вызовом parseInt).
  • Если строка не соответствует допустимому числовому формату или значение выходит за пределы диапазона представления (пример: слишком большое число для int в указанной системе счисления), будет выброшено NumberFormatException.

Примечание о кэшировании: спецификация языка не гарантирует конкретный диапазон кэширования, но большинство реализаций кэшируют минимально значения от -128 до 127. Следует не полагаться на то, что все экземпляры для одинаковых значений будут == друг другу во всех диапазонах.

Примеры простого использования

Короткие примеры с кодом и результатом.

valueOf(int) и сравнение ссылок:

public class Ex1 {
    public static void main(String[] args) {
        Integer a = Integer.valueOf(100);
        Integer b = Integer.valueOf(100);
        Integer c = Integer.valueOf(1000);
        Integer d = Integer.valueOf(1000);
        System.out.println(a == b);     // сравнение ссылок
        System.out.println(c == d);
        System.out.println(a.equals(b));
    }
}
true
false
true

valueOf(String) и valueOf(String, radix):

public class Ex2 {
    public static void main(String[] args) {
        Integer a = Integer.valueOf("123");
        Integer b = Integer.valueOf("7B", 16); // 0x7B == 123
        System.out.println(a);    
        System.out.println(b);
    }
}
123
123

Поведение при неправильном формате:

public class Ex3 {
    public static void main(String[] args) {
        try {
            Integer.valueOf("12a");
        } catch (NumberFormatException e) {
            System.out.println("Ошибка: " + e.getMessage());
        }
    }
}
Ошибка: For input string: "12a"

Аналоги в Java и отличия

  • Integer.parseInt(String) - возвращает примитив int. Предпочтительнее, когда нужен примитив и требуется избежать лишней упаковки.
  • Integer.decode(String) - разбирает строку с автоматическим определением основания по префиксам ("0x"/"0X"/"#" для шестнадцатеричных, ведущий ноль для восьмеричных). Возвращает int, полезна при разборе строк с префиксами.
  • Integer.parseUnsignedInt/Integer.toUnsignedLong - работают с беззнаковыми значениями; используются, если требуется обработать значения >= 2^31 как беззнаковые.
  • new Integer(int) - напрямую создает новый объект. В большинстве случаев хуже по производительности, чем valueOf, так как не использует кэш.

Выбор между ними зависит от необходимости получить объект-обертку, экономии памяти (кэш) или обработки примитивного типа.

Эквиваленты в других языках и отличия

Краткие соответствия и примеры.

  • Python
    # Python
    x = int("123")
    print(x)
    123

    int() возвращает примитивный тип int (необъектную обертку). В случае неверной строки выбрасывает ValueError.

  • JavaScript
    // JavaScript
    let a = Number("123");
    let b = parseInt("7B", 16);
    console.log(a);
    console.log(b);
    123
    123

    parseInt принимает radix, но возвращает NaN при ошибке; Number("") даст 0, Number("abc") даст NaN.

  • PHP
    // PHP
    echo (int)"123" . "\n";
    echo intval("123") . "\n";
    123
    123

    Приведение возвращает числовое значение; поведение при некорректной строке отличается (обычно возвращается 0).

  • C#
    // C#
    using System;
    class P{static void Main(){
      int a = int.Parse("123");
      int b; bool ok = int.TryParse("12a", out b);
      Console.WriteLine(a);
      Console.WriteLine(ok);
    }}
    
    123
    False

    int.Parse выбрасывает исключение при ошибке, TryParse возвращает false без исключения.

  • Go
    // Go
    package main
    import (
      "fmt"
      "strconv"
    )
    func main(){
      v, err := strconv.Atoi("123")
      fmt.Println(v, err == nil)
    }
    123 true

    В Go возвращается значение и ошибка одновременно.

  • Lua
    -- Lua
    print(tonumber("123"))
    123
  • Kotlin
    // Kotlin
    val a: Int = "123".toInt()
    val b: Int? = "abc".toIntOrNull()
    println(a)
    println(b)
    123
    null

    Kotlin предоставляет безопасный метод toIntOrNull, возвращающий null при ошибке.

  • SQL
    -- SQL (пример для PostgreSQL)
    SELECT CAST('123' AS INTEGER);
    123

    В SQL преобразование зависит от СУБД; при неверном формате часто будет ошибка типа.

Отличия от Java: в большинстве динамических языков отсутствуют объектные обертки с кэшем, поведение при ошибках и возвращаемые типы различаются (исключение vs специальное значение vs кортеж с ошибкой).

Типичные ошибки и ловушки

  • Сравнение ссылок (==) вместо equals()

    Integer a = Integer.valueOf(1000);
    Integer b = Integer.valueOf(1000);
    System.out.println(a == b);
    false

    Поскольку для больших значений обычно возвращаются разные объекты, == даст false, тогда как a.equals(b) вернёт true.

  • Ожидание кэширования за пределами диапазона

    Integer x = Integer.valueOf(200);
    Integer y = Integer.valueOf(200);
    System.out.println(x == y);
    false

    Кэш обычно ограничен; нельзя полагаться на то, что одинаковые числовые значения всегда имеют одинаковую ссылку.

  • Передача null в valueOf(String)

    Integer.valueOf(null);
    Exception in thread "main" java.lang.NumberFormatException: null

    При null будет выброшено NumberFormatException; проверка на null нужна до вызова.

  • Неправильный radix или формат

    Integer.valueOf("19", 8);
    Exception in thread "main" java.lang.NumberFormatException: For input string: "19"

    Цифра '9' недопустима для восьмеричной системы счисления, что приводит к NumberFormatException.

  • Ожидание новой инстанции

    Integer a = Integer.valueOf(10);
    Integer b = new Integer(10);
    System.out.println(a == b);
    false

    new Integer всегда создаёт новый объект; смешивание подходов может привести к неожиданным результатам при сравнении ссылок.

Изменения и заметки по версиям

API Integer.valueOf остаётся стабильным в современных версиях JDK. Поведение кэширования исторически присутствует и в большинстве реализаций охватывает диапазон от -128 до 127. Некоторые реализации JVM позволяют расширять верхнюю границу кэша с помощью внутренних настроек/свойств среды, но это не часть официального и поддерживаемого API и не рекомендуется полагаться на такие настройки в переносимом коде.

В стандартной библиотеке появились дополнительные методы для беззнаковой арифметики и разбора (например, parseUnsignedInt и т. п.), которые дополняют инструментарий работы с целыми числами, но не заменяют поведение valueOf.

Расширенные и редкие сценарии использования

Несколько детализированных примеров с объяснениями.

1) Использование valueOf в потоках данных для экономии памяти при большом количестве однотипных значений:

Пример java
import java.util.*;
class PoolExample {
    public static void main(String[] args) {
        List list = new ArrayList<>();
        for (int i = 0; i < 100_000; i++) {
            list.add(Integer.valueOf(42)); // переиспользуется кэшированный объект
        }
        System.out.println("size=" + list.size());
    }
}
size=100000

Объяснение: использование valueOf для часто повторяющихся маленьких значений уменьшает количество аллокаций по сравнению с генерацией новых объектов.

2) Разбор беззнаковых чисел и упаковка в Integer (через parseUnsignedInt):

Пример java
public class UnsignedWrap {
    public static void main(String[] args) {
        int parsed = Integer.parseUnsignedInt("4294967295"); // 2^32-1
        Integer boxed = Integer.valueOf(parsed);
        System.out.println(parsed);
        System.out.println(boxed);
    }
}
-1
-1

Объяснение: parseUnsignedInt возвращает числовое значение в диапазоне int, представляющее беззнаковое число; при упаковке в Integer отображение остается как signed int (например, 4294967295 -> -1 в signed представлении).

3) Использование valueOf в методах Map.computeIfAbsent для кэширования значений-счетчиков:

Пример java
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
class CounterMap {
    static ConcurrentMap map = new ConcurrentHashMap<>();
    static void inc(String key) {
        map.compute(key, (k, v) -> v == null ? Integer.valueOf(1) : Integer.valueOf(v + 1));
    }
    public static void main(String[] args) {
        inc("a"); inc("a");
        System.out.println(map.get("a"));
    }
}
2

Объяснение: использование Integer.valueOf устраняет лишние new-инстанции для небольших чисел в горячем коде.

4) Нестандартный парсинг с пользовательской нормализацией и безопасной упаковкой:

Пример java
public class SafeParse {
    public static Integer safeValueOf(String s, int radix) {
        if (s == null) return null;
        s = s.strip();
        if (s.isEmpty()) return null;
        try {
            return Integer.valueOf(Integer.parseInt(s, radix));
        } catch (NumberFormatException e) {
            return null;
        }
    }
    public static void main(String[] args) {
        System.out.println(safeValueOf(" 7B ", 16));
        System.out.println(safeValueOf("", 10));
        System.out.println(safeValueOf(null, 10));
    }
}
123
null
null

Объяснение: обёртка, возвращающая null вместо исключения, удобна в потоках обработки данных, где исключения нежелательны.

5) Нюансы автозапаковки/распаковки и NPE:

Пример java
public class UnboxNPE {
    public static void main(String[] args) {
        Integer x = null;
        try {
            int y = x; // распаковка null
            System.out.println(y);
        } catch (NullPointerException e) {
            System.out.println("NullPointerException при распаковке");
        }
    }
}
NullPointerException при распаковке

Объяснение: метод valueOf не вызывает NPE сам по себе, но упаковка/распаковка Integer в int может привести к NPE при распаковке null.

джава Integer.valueOf function comments

En
Integer.valueOf Returns an Integer instance representing the specified int value