Integer.valueOf: примеры (JAVA)
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 в потоках данных для экономии памяти при большом количестве однотипных значений:
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):
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 для кэширования значений-счетчиков:
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) Нестандартный парсинг с пользовательской нормализацией и безопасной упаковкой:
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:
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.