0Pricing
Java Academy · Lesson

Widening and Narrowing Conversions

Learn automatic widening conversions and how to perform explicit narrowing casts safely.

Widening and Narrowing Conversions is a free Java Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Type Conversions in Java

Java allows converting values between compatible types. There are two directions:

  • Widening — converting to a larger type (safe, automatic)
  • Narrowing — converting to a smaller type (risky, requires explicit cast)

Widening Conversion

Widening happens automatically when you assign a value to a larger compatible type. No data is lost because the target type can represent all values of the source.

Widening order: byte → short → int → long → float → double

byte b = 42;
short s = b;    // byte → short (widening)
int i = s;      // short → int (widening)
long l = i;     // int → long (widening)
float f = l;    // long → float (widening)
double d = f;   // float → double (widening)

System.out.println(d); // 42.0

Narrowing Conversion

Narrowing must be done explicitly with a cast operator (type). The value may be truncated or corrupted if it doesn't fit in the target type.

double price = 99.99;
int wholePart = (int) price; // narrows — decimal truncated
System.out.println(wholePart); // 99 (not rounded!)

long bigNum = 130L;
byte small = (byte) bigNum;  // 130 overflows byte (max 127)
System.out.println(small);   // -126 (unexpected!)

Overflow During Narrowing

When a value overflows during narrowing, Java wraps it around using modular arithmetic — no exception is thrown. You must guard against this manually.

int million = 1_000_000;
byte narrowed = (byte) million;
System.out.println(narrowed); // 64 (wraps around)

// Safe narrowing: check bounds first
if (million >= Byte.MIN_VALUE && million <= Byte.MAX_VALUE) {
    byte safe = (byte) million;
} else {
    System.out.println("Value doesn't fit in byte!");
}

char and int Conversions

char is a 16-bit unsigned integer representing a Unicode code point. It widens to int automatically but must be explicitly cast from int back to char.

char letter = 'A';
int code = letter;          // widening: char → int
System.out.println(code);   // 65

int nextCode = code + 1;
char nextLetter = (char) nextCode; // narrowing: int → char
System.out.println(nextLetter);    // B

// Useful for Caesar cipher shifts
char shifted = (char) ('a' + 3);
System.out.println(shifted); // d

Floating-Point to Integer Truncation

Casting a floating-point number to an integer truncates toward zero — it does not round. Use Math.round() if you need rounding.

double pos = 3.9;
double neg = -3.9;

System.out.println((int) pos);         // 3 (not 4)
System.out.println((int) neg);         // -3 (not -4)
System.out.println(Math.round(pos));   // 4
System.out.println(Math.round(neg));   // -4

String to Number Conversions

Parsing a String to a number uses wrapper methods — not casting. Passing a non-numeric string throws NumberFormatException.

String input = "42";
int parsed = Integer.parseInt(input);
double parsedD = Double.parseDouble("3.14");

System.out.println(parsed + 1);  // 43
System.out.println(parsedD);     // 3.14

try {
    int bad = Integer.parseInt("abc");
} catch (NumberFormatException e) {
    System.out.println("Not a valid number!");
}

Number to String Conversions

Converting a number to a String can be done with String.valueOf(), Integer.toString(), or string concatenation with "".

int score = 95;
String s1 = String.valueOf(score);    // "95"
String s2 = Integer.toString(score);  // "95"
String s3 = score + "";              // "95" (concat trick)

System.out.println(s1.getClass().getSimpleName()); // String

// Converting to different bases
System.out.println(Integer.toBinaryString(42)); // 101010
System.out.println(Integer.toHexString(255));   // ff

Promotion in Expressions

In arithmetic expressions, Java automatically promotes operands:

  • byte, short, char → promoted to int before the operation
  • If either operand is long, the result is long
  • If either is float or double, the result matches the wider type
byte x = 10;
byte y = 20;
// byte z = x + y; // compile error! sum is promoted to int
int z = x + y;      // correct

long a = 100L;
float b = 2.5f;
double result = a * b; // long * float → double
System.out.println(result); // 250.0

Compound Assignment Operators

Compound operators like +=, -=, *= include an implicit narrow cast. This lets you write concise code with byte and short variables.

byte count = 100;
// count = count + 1; // compile error — int result needs cast
count += 1;           // OK — compound op casts automatically
System.out.println(count); // 101

short total = 1000;
total *= 2;  // implicit narrow cast included
System.out.println(total); // 2000

Practical: Safe Integer Parsing

A real-world pattern: parse user input safely, validate range, and narrow to the exact type needed.

public static byte parseAsByte(String input) {
    int value = Integer.parseInt(input); // can throw NumberFormatException
    if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
        throw new IllegalArgumentException(
            "Value " + value + " out of byte range");
    }
    return (byte) value;
}

// Usage
System.out.println(parseAsByte("100")); // 100
System.out.println(parseAsByte("200")); // IllegalArgumentException

Quick Check

What is the output of the following code?

double d = -7.8;
int i = (int) d;
System.out.println(i);

Recap: Widening and Narrowing

Key takeaways:

  • Widening is automatic and safe: byte→short→int→long→float→double
  • Narrowing needs an explicit cast and may lose data or cause overflow
  • char widens to int; int can be narrowed back to char with a cast
  • Floating-point to int truncates toward zero (not round)
  • Use Integer.parseInt/Double.parseDouble to convert Strings to numbers
  • Compound operators (+=, *=) include implicit narrowing casts

Frequently asked questions

Is the “Widening and Narrowing Conversions” lesson free?

Yes — the full text of “Widening and Narrowing Conversions” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.

What will I learn in “Widening and Narrowing Conversions”?

Learn automatic widening conversions and how to perform explicit narrowing casts safely. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Java Academy?

No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Widening and Narrowing Conversions” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Java Academy lesson?

Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Primitive vs Reference Types
  2. Widening and Narrowing Conversions
  3. The instanceof Operator
  4. Type Casting in Practice
← Back to Java Academy