Java Type Casting — Widening, Narrowing & String Conversions

3 minute read

Sometimes you need to convert a value from one type to another — for example, turning an int into a double or converting a String to a number. This is called type casting.


Two Types of Casting

Widening (Automatic)                    Narrowing (Manual)
byte → short → int → long → float → double    double → float → long → int → short → byte
         Safe — no data loss                    Risky — possible data loss

Widening Casting (Automatic)

When you assign a smaller type to a larger type, Java converts automatically — no data is lost:

public class WideningDemo {
    public static void main(String[] args) {
        int myInt = 100;
        long myLong = myInt;       // int → long (automatic)
        float myFloat = myLong;    // long → float (automatic)
        double myDouble = myFloat; // float → double (automatic)

        System.out.println("int:    " + myInt);     // 100
        System.out.println("long:   " + myLong);    // 100
        System.out.println("float:  " + myFloat);   // 100.0
        System.out.println("double: " + myDouble);  // 100.0
    }
}

Output:

int:    100
long:   100
float:  100.0
double: 100.0

This is safe because a double can hold any value that an int can hold.


Narrowing Casting (Manual)

When you go from a larger type to a smaller type, you must explicitly cast — and you may lose data:

public class NarrowingDemo {
    public static void main(String[] args) {
        double myDouble = 9.78;
        int myInt = (int) myDouble;  // Manual cast with (int)

        System.out.println("double: " + myDouble);  // 9.78
        System.out.println("int:    " + myInt);      // 9  ← Decimal part lost!
    }
}

Output:

double: 9.78
int:    9

Important: Narrowing casting truncates — it chops off the decimal. It does NOT round. (int) 9.99 gives 9, not 10.

More Examples

double value = 3.99;
int truncated = (int) value;     // 3 (not 4!)

long bigNum = 3000000000L;
int overflow = (int) bigNum;     // -1294967296  ← Overflow!

int number = 65;
char letter = (char) number;     // 'A' (ASCII 65 = 'A')

String to Number Conversions

String → int

String text = "42";
int number = Integer.parseInt(text);
System.out.println(number + 8);  // 50 (math, not string concatenation)

String → double

String text = "3.14";
double number = Double.parseDouble(text);
System.out.println(number * 2);  // 6.28

String → long

String text = "9000000000";
long number = Long.parseLong(text);

What Happens with Invalid Input?

String text = "hello";
int number = Integer.parseInt(text);  // Throws NumberFormatException!
Exception in thread "main" java.lang.NumberFormatException: For input string: "hello"

You’ll learn to handle this in Module 4: Exception Handling.


Number to String Conversions

Method 1: String.valueOf()

int age = 25;
String text = String.valueOf(age);  // "25"

Method 2: Concatenation with ""

int age = 25;
String text = age + "";  // "25" — quick but less readable

Method 3: Integer.toString()

int age = 25;
String text = Integer.toString(age);  // "25"

Casting with char

Characters and integers are interchangeable in Java because every character has a numeric code (ASCII/Unicode):

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

int code = 66;
char fromCode = (char) code;      // 'B' (narrowing)
System.out.println(fromCode);     // B

Fun Example: Print the Alphabet

for (int i = 65; i <= 90; i++) {
    System.out.print((char) i + " ");
}
// Output: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

The instanceof Operator (Preview)

When working with objects (covered in OOP Module), you can check an object’s type before casting:

Object obj = "Hello";
if (obj instanceof String s) {     // Java 16+ pattern matching
    System.out.println(s.length()); // Safe to use as String
}

Common Mistakes

Mistake: Assuming Narrowing Rounds

int x = (int) 2.9;   // 2, NOT 3

If you want rounding, use Math.round():

int x = (int) Math.round(2.9);  // 3

Mistake: Integer Division Surprise

int result = 7 / 2;         // 3, not 3.5!
double result2 = 7 / 2;     // 3.0 (still integer division, then widened)
double result3 = 7.0 / 2;   // 3.5 (one operand is double → double division)
double result4 = (double) 7 / 2;  // 3.5 (cast first, then divide)

Try It Yourself

Write a program that:

  1. Takes a temperature in Fahrenheit as a double (e.g., 98.6)
  2. Converts it to Celsius using: C = (F - 32) × 5 / 9
  3. Prints both the exact double result and the truncated int result

Expected output:

Fahrenheit: 98.6
Celsius (exact): 37.0
Celsius (truncated): 37

Summary

Operation Syntax Example
Widening (auto) Just assign double d = myInt;
Narrowing (manual) (targetType) value int i = (int) 3.99;
String → int Integer.parseInt(s) Integer.parseInt("42")
String → double Double.parseDouble(s) Double.parseDouble("3.14")
Number → String String.valueOf(n) String.valueOf(42)
Truncation Chops decimals (int) 9.99 → 9

What’s Next?

Now let’s learn all the operations you can perform on your data:

Java Operators →

Updated: