Convert int to String in Java (Integer.toString vs valueOf)

Convert int to String in Java with Integer.toString(), String.valueOf() and format(), plus null Integer, locale digits, hex and long to String.

Decision diagram for converting int to String in Java, from a plain int to a nullable Integer, formatting, other bases and long

The two standard ways to convert an int to a String in Java are Integer.toString(n) and String.valueOf(n), and both return the decimal text of the number, such as “42” for 42. The two calls give the same result, because String.valueOf(int) calls Integer.toString(int) inside the JDK.

We convert numbers to text to show them in a UI, to write them to a CSV file, a log line or a JSON field, and to build keys such as room-204. The same methods exist for long as Long.toString() and String.valueOf(long).

The following example converts an order quantity in four common ways.

int quantity = 42;
String byToString = Integer.toString(quantity);        // "42"
String byValueOf = String.valueOf(quantity);           // "42"
String byConcat = "" + quantity;                       // "42"
String padded = String.format(Locale.ROOT, "%05d", quantity);   // "00042"

We can see that all four give the digits, and only String.format() adds formatting. We pick the right method for each case, handle a null Integer, look at a locale trap in String.format(), convert to other bases, cover long to String, and compare the methods by what they compile to.

1. Choosing Between Integer.toString() and String.valueOf()

The static method Integer.toString(int) returns the signed decimal form of the number, with a minus sign for negative values and no plus sign for positive ones. The method String.valueOf(int) returns Integer.toString(i) in the JDK 25 source, so the two always return the same text.

Decision diagram for converting int to String in Java, from a plain int to a nullable Integer, formatting, other bases and long
Integer.toString() or String.valueOf() covers a plain int; the other methods are for null values, formatting and other bases
String zero = Integer.toString(0);                  // "0"
String negative = Integer.toString(-40);            // "-40"
String max = String.valueOf(Integer.MAX_VALUE);     // "2147483647"
String min = String.valueOf(Integer.MIN_VALUE);     // "-2147483648"

Neither method throws an exception for an int, because every int value has a decimal form. A wrong number in the output comes from the arithmetic before the call. For example, Integer.MAX_VALUE + 1 overflows to -2147483648 before it reaches toString(), and Math.addExact() reports the overflow instead.

int wrapped = Integer.MAX_VALUE + 1;
String overflowText = Integer.toString(wrapped);           // "-2147483648"
int checked = Math.addExact(Integer.MAX_VALUE, 1);         // ArithmeticException: integer overflow

For a primitive int, we use either method and stay consistent in the code base. Many teams prefer String.valueOf() because the same call name works for long, double, boolean, char and objects.

2. Converting an Integer That Can Be null

Fields such as an optional quantity in a request DTO are often Integer objects, and they can be null. The conversion methods treat null differently, and picking the wrong one either prints the text “null” or throws NullPointerException.

Integer maybeQty = null;
String asText = String.valueOf(maybeQty);           // "null"
String withDefault = Objects.toString(maybeQty, "");   // ""
String unboxed = Integer.toString(maybeQty);        // NullPointerException

The call String.valueOf(maybeQty) picks the valueOf(Object) overload, which returns the four letters “null”. The call Integer.toString(maybeQty) unboxes the Integer to an int first, and the unboxing throws. The wrapper classes guide explains boxing and unboxing in detail.

Say a shop exports orders to CSV, and the gift-wrap count is empty for most orders. With String.valueOf(), the file contains null in that column and the import on the other side fails. The call Objects.toString(value, “”) writes an empty cell instead.

3. Concatenation, String.format() and formatted()

Adding an int to a string with + converts it to its decimal text. Since Java 9, the compiler turns concatenation into one invokedynamic call (JEP 280), so “Room ” + room is as clear as it looks and fast. For the number alone, “” + n works, but String.valueOf(n) says what we mean.

int room = 204;
String label = "Room " + room;                            // "Room 204"
String key = "room-" + room;                              // "room-204"
String built = new StringBuilder("Floor ").append(room / 100).toString();   // "Floor 2"

We use String.format(), or the instance method formatted() from Java 15, when the text needs leading zeros, a fixed width or grouping separators. The left padding guide has more padding patterns.

String orderNo = String.format(Locale.ROOT, "order-%06d", 381);      // "order-000381"
String grouped = String.format(Locale.ROOT, "%,d", 1234567);       // "1,234,567"
String width = String.format(Locale.ROOT, "[%5d]", 42);              // "[   42]"

Without a Locale argument, String.format() uses the default locale of the JVM, which can change the digits themselves. On a server whose default locale is Arabic (Egypt), %d prints Arabic-Indic digits, and a file meant for another program contains numbers it cannot parse.

String arabic = String.format(Locale.forLanguageTag("ar-EG"), "%d", 123);
boolean asciiDigits = arabic.equals("123");                     // false
int firstChar = arabic.charAt(0);                               // 1633
String fixed = String.format(Locale.ROOT, "%d", 123);          // "123"

The value 1633 is U+0661, the Arabic-Indic digit one. The methods Integer.toString() and String.valueOf() always produce ASCII digits, so we use them, or pass Locale.ROOT to Formatter, for text that programs read. For text that people read, a locale-aware NumberFormat is the right tool.

String german = NumberFormat.getIntegerInstance(Locale.GERMANY).format(1234567);   // "1.234.567"

4. Converting int to Binary, Octal, Hex and Other Bases

The Integer class converts to other bases as well. The method toString(int, radix) takes any radix from 2 to 36 and keeps the minus sign, while toBinaryString(), toOctalString() and toHexString() treat the value as unsigned, so a negative number shows its two’s complement bits.

String binary = Integer.toBinaryString(10);              // "1010"
String octal = Integer.toOctalString(8);                 // "10"
String hex = Integer.toHexString(255);                   // "ff"
String base36 = Integer.toString(35, 36);                // "z"
String signed = Integer.toString(-255, 2);               // "-11111111"
String unsignedHex = Integer.toHexString(-1);            // "ffffffff"
String unsignedDec = Integer.toUnsignedString(-1);       // "4294967295"

For fixed-width hex output, such as color codes or checksums, HexFormat (Java 17) pads to 8 digits for an int.

String hex8 = HexFormat.of().toHexDigits(255);           // "000000ff"

5. Converting long to String

A long converts the same way, with Long.toString(long) or String.valueOf(long), which calls Long.toString(). We need long for values above 2,147,483,647, such as file sizes in bytes, epoch milliseconds or database IDs.

long fileBytes = 5_000_000_000L;
String size = Long.toString(fileBytes);                   // "5000000000"
String sizeToo = String.valueOf(fileBytes);               // "5000000000"
String millis = "ts-" + 1760054400000L;                   // "ts-1760054400000"
String longHex = Long.toHexString(255L);                  // "ff"
String unsignedLong = Long.toUnsignedString(-1L);         // "18446744073709551615"

The L suffix matters for literals above the int range, because 5_000_000_000 without it does not compile. A null Long behaves like a null Integer, so Long.toString() throws and String.valueOf() returns “null”.

Long missingId = null;
String idText = String.valueOf(missingId);                // "null"
String idFails = Long.toString(missingId);                // NullPointerException

6. Which int to String Method Is Fastest?

The compiled bytecode shows how much work each method does. The following output comes from javap -c on JDK 25 for four one-line methods that each convert an int parameter.

static java.lang.String a(int);        // Integer.toString(n)
   1: invokestatic  #7   // Method java/lang/Integer.toString:(I)Ljava/lang/String;
static java.lang.String b(int);        // String.valueOf(n)
   1: invokestatic  #13  // Method java/lang/String.valueOf:(I)Ljava/lang/String;
static java.lang.String c(int);        // "" + n
   1: invokedynamic #18, 0  // InvokeDynamic #0:makeConcatWithConstants:(I)Ljava/lang/String;
static java.lang.String d(int);        // String.format("%d", n)
   0: ldc           #21  // String %d
   3: anewarray     #2   // class java/lang/Object
   9: invokestatic  #23  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
  13: invokestatic  #26  // Method java/lang/String.format:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;

The first two are one static call, and String.valueOf() adds one more call that the JIT compiler inlines. Concatenation goes through a method handle that is linked once per call site. The String.format() call boxes the number, creates an array and parses the format string on every call, so it is the slowest of the four and belongs only where we need formatting.

For exact numbers on our hardware, we measure with JMH instead of a loop with System.nanoTime(), because the JIT compiler removes work whose result is never used. The string concatenation performance guide compares the concatenation options.

String templates (STR.”\{n}”) were a preview feature in Java 21 and 22 and were withdrawn, so code that uses them does not compile on Java 23 and later.

// does not compile: String templates were withdrawn after Java 22
String text = STR."\{quantity}";

7. int to String FAQs

After the basic conversion, readers look for leading zeros, the reverse conversion, the old new Integer() habit and arrays of numbers.

7.1. What is the difference between String.valueOf() and Integer.toString()?

For an int, none, because String.valueOf(int) returns Integer.toString(int). The difference appears for a null Integer, where String.valueOf() returns “null” and Integer.toString() throws NullPointerException, as section 2 shows.

7.2. How do we convert an int to a String with leading zeros?

We use %0Nd in String.format(), where N is the total width, and pass Locale.ROOT so the digits are ASCII.

String code = String.format(Locale.ROOT, "%04d", 7);   // "0007"

7.3. How do we convert a String back to an int?

We call Integer.parseInt(), which either returns an int or throws NumberFormatException for text that is not a number. The guide to convert a String to int covers the safe patterns.

7.4. Is new Integer(n).toString() still a good way?

No. The Integer(int) constructor still compiles, but it has been deprecated since Java 9, because it creates a new object every time, and the javac compiler prints a deprecation warning. The call Integer.toString(n) gives the same text without creating an Integer at all.

7.5. How do we convert an int array to a String?

We use Arrays.toString() for the bracketed form, or a stream with Collectors.joining() for a custom separator.

int[] scores = {7, 9, 10};
String bracketed = Arrays.toString(scores);                                                     // "[7, 9, 10]"
String csv = Arrays.stream(scores).mapToObj(String::valueOf).collect(Collectors.joining(","));   // "7,9,10"

8. Conclusion

For a plain int, Integer.toString() and String.valueOf() return the same ASCII digits, and the same pair exists for long. For a nullable Integer, Objects.toString(value, “”) avoids both the “null” text and the NullPointerException.

Concatenation is fine inside a larger message, and String.format() is for padding and grouping, with Locale.ROOT for machine-readable output. The Java String tutorial collects the other conversion guides.

9. References

Happy Learning !!

Source Code on Github

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.