Back to Blog
Java

Java int Type: Range, Overflow, and Practical Usage

java int type: Understand the Java int type: its 32-bit range, arithmetic promotion, overflow behavior, and when to choose int over long or Integer.

Java primitivesInteger overflowAutoboxingNumeric type promotionInteger parsing
Illustration of the Java int type showing its 32-bit range boundary and overflow wrapping behavior.

The java int type is a 32-bit signed primitive that stores whole numbers from -2,147,483,648 to 2,147,483,647. It is the default choice for integer arithmetic in most Java programs because it requires no object allocation and maps directly to JVM bytecode instructions. Understanding its range, promotion rules, and overflow behavior matters before you write your first loop, because these details determine when int is sufficient and when you must move to long, BigInteger, or a wrapper type.

Declaring and Initializing int Variables

An int variable is declared with the int keyword. Local variables must be assigned a value before they are read; the compiler rejects code that reads an uninitialized local. Instance and static fields, by contrast, default to 0 when an object or class is loaded.

int count = 42; int total; // must be assigned before any read
public class Counter { private int value; // defaults to 0 }

The final modifier makes an int constant. A final int must be assigned exactly once, either at declaration or in a constructor. This is the standard way to define named constants such as MAX_RETRIES or DEFAULT_PORT.

final int MAX_RETRIES = 3;

Arithmetic Behavior and Type Promotion

When two int values are combined with +, -, *, /, or %, the result is an int. Integer division truncates toward zero, so 7 / 2 evaluates to 3, not 3.5. The modulo operator % returns the remainder with the sign of the dividend.

int a = 7; int b = 2; int quotient = a / b; // 3 int remainder = a % b; // 1

If one operand in a binary operation is a long, float, or double, the int is promoted to that wider type before the operation runs. This is binary numeric promotion, and it is why 5 / 2.0 produces 2.5 while 5 / 2 produces 2. The same rule applies to comparison operators and to method arguments when a widening conversion is available.

Compound assignment operators such as +=, -=, *=, and %= perform an implicit cast back to int. That means int x = 5; x += 3.7; compiles, truncates 3.7 to 3, and stores 8 in x. The explicit cast is hidden, which can surprise developers who expect a compile error.

Overflow and How to Detect It

Because int is a fixed-width two's complement value, arithmetic that exceeds the range wraps around silently. Integer.MAX_VALUE + 1 evaluates to Integer.MIN_VALUE, and Integer.MIN_VALUE - 1 evaluates to Integer.MAX_VALUE. There is no automatic exception, and the result is often a negative number where a positive one was expected.

int max = Integer.MAX_VALUE; int overflowed = max + 1; // -2147483648

The java.lang.Math class provides exact arithmetic methods that throw ArithmeticException on overflow: addExact, subtractExact, multiplyExact, and negateExact. These are useful in financial calculations, hash computations, or any code where a wrapped value would corrupt the result.

try { int result = Math.addExact(Integer.MAX_VALUE, 1); } catch (ArithmeticException e) { // handle the overflow explicitly }

Overflow also occurs in intermediate expressions. Multiplying two large int values can overflow even when the final result would fit in a long. In that case, cast one operand to long before the multiplication:

long product = (long) a * b;

The cast forces the multiplication to run in 64-bit arithmetic, avoiding the intermediate 32-bit overflow.

int vs Integer: Autoboxing and Performance

Integer is the boxed reference counterpart of int. Autoboxing converts an int to an Integer automatically when the context requires an object, such as when storing values in a List<Integer> or a Map<String, Integer>. Unboxing converts in the reverse direction.

List<Integer> numbers = new ArrayList<>(); numbers.add(42); // autoboxing int first = numbers.get(0); // unboxing

Each autoboxing conversion outside the JVM's cached range of -128 to 127 allocates a new Integer object. The JVM caches Integer instances in that range, so conversions there reuse existing objects. In a hot loop that stores many values into a collection, the allocation cost of boxing can become measurable. The Integer.valueOf method applies the same cache, while new Integer(value) always allocates, which is why the constructor is deprecated since Java 9.

Unboxing a null Integer throws NullPointerException. This is a common failure when a collection contains null values or when a database result maps to an Integer that was never set.

Integer maybeNull = getValue(); int value = maybeNull; // NullPointerException if maybeNull is null

Parsing and Converting int Values

Integer.parseInt converts a String to an int. It accepts an optional leading sign and throws NumberFormatException for empty strings, non-digit characters, or values outside the int range. The overload Integer.parseInt(String, int radix) parses values in bases other than 10.

int decimal = Integer.parseInt("1234"); int hex = Integer.parseInt("ff", 16); // 255

For the reverse direction, Integer.toString(int) and String.valueOf(int) produce the decimal representation. Integer.toHexString, Integer.toOctalString, and Integer.toBinaryString produce alternate bases.

String s = Integer.toString(255); // "255" String hex = Integer.toHexString(255); // "ff"

When parsing user input, catching NumberFormatException is necessary because the input cannot be trusted. The Integer class also provides compare, max, min, and sum static methods that avoid the overhead of boxing when working with primitive values.

Choosing Between int and Other Numeric Types

int is the right default for counters, array indices, loop variables, and most whole-number calculations. Use long when a value may exceed 2,147,483,647, such as timestamps in milliseconds or file sizes in bytes. Use byte or short only when memory footprint is a measured constraint in large arrays, because arithmetic on those types is promoted to int anyway. Use BigInteger for arbitrary-precision arithmetic, which is necessary for cryptographic operations or very large combinatorial values but carries a significant performance cost.

TypeBit widthRangeTypical use
byte8-128 to 127Binary data, compact arrays
short16-32,768 to 32,767Legacy formats, compact storage
int32-2,147,483,648 to 2,147,483,647Default integer arithmetic
long64-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807Large counters, timestamps

The decision between int and long should be based on the actual range of values the code can encounter, not on the size of the input. A counter that increments once per request in a high-traffic service can exceed the int range over a long enough period. When the range is uncertain, long is the safer choice, and the JVM handles 64-bit arithmetic efficiently on modern hardware.

java int type: Practical Usage and Code Examples | RYUSLOG DEV