Skip to content
Laviyx Learn

Try

Java course menu

Java Type Casting: Widening, Narrowing and Converting Strings

Learn type casting in Java: automatic widening conversions, explicit narrowing casts and data loss, integer division and casting, rounding with Math.round, converting strings to numbers with Integer.parseInt and back with String.valueOf, and NumberFormatException.

Beginner9 min readUpdated
On this page

Converting a value from one type to another is called casting (or type conversion). Java converts automatically when it is safe, and makes you ask explicitly when information could be lost.

Widening: automatic and safe#

Moving to a type that can hold every possible value of the original is called widening, and Java does it automatically:

byte → short → int → long → float → double, and char → int.

Java
public class Main {
    public static void main(String[] args) {
        int apples = 7;
        double weight = 0.25;
        long bigCount = apples;          // int to long
        double total = apples * weight;  // apples is widened to double

        System.out.println(bigCount + " " + total);
        System.out.println('A' + 1);     // char widened to int
    }
}
Output
7 1.75
66

Narrowing: explicit, and you may lose data#

Going the other way (for example double to int) can lose information, so Java requires an explicit cast: the target type in parentheses:

Java
public class Main {
    public static void main(String[] args) {
        double price = 99.99;
        int rupees = (int) price;      // the fraction is dropped
        int negative = (int) -3.9;

        long big = 3_000_000_000L;
        int overflowed = (int) big;    // too big for int: wraps around

        System.out.println(rupees + " " + negative + " " + overflowed);
    }
}
Output
99 -3 -1294967296

Casting a decimal to an integer truncates towards zero: 99.99 becomes 99 and −3.9 becomes −3. Casting a value that does not fit keeps only the low bits, which gives a nonsense number.

Without the cast, the compiler refuses:

Java
public class Main {
    public static void main(String[] args) {
        double price = 99.99;
        int rupees = price;   // error: possible lossy conversion from double to int
    }
}

Casting to fix integer division#

Dividing two integers gives an integer. Cast one operand before dividing:

Java
public class Main {
    public static void main(String[] args) {
        int totalMarks = 437;
        int subjects = 5;

        double wrong = totalMarks / subjects;
        double average = (double) totalMarks / subjects;

        System.out.println(wrong + " " + average);
    }
}
Output
87.0 87.4

(double) (totalMarks / subjects) would still give 87.0, because the division would already have happened.

Rounding instead of truncating#

Math provides proper rounding:

Java
public class Main {
    public static void main(String[] args) {
        System.out.println(Math.round(2.5) + " " + Math.round(2.4) + " " + Math.round(-2.5));
        System.out.println(Math.floor(2.7) + " " + Math.ceil(2.1));
        System.out.printf("%.2f%n", 3.14159);
    }
}
Output
3 2 -2
2.0 3.0
3.14
  • Math.round rounds to the nearest whole number (halves go up, so −2.5 becomes −2) and returns a long for a double argument.
  • Math.floor and Math.ceil round down and up, returning a double.
  • For display, printf / String.format with %.2f rounds the printed text only.

Strings to numbers#

Text from users or files must be converted before doing arithmetic:

Java
public class Main {
    public static void main(String[] args) {
        String a = "42";
        String b = "8";
        System.out.println(a + b);                                   // joins text
        System.out.println(Integer.parseInt(a) + Integer.parseInt(b)); // adds numbers

        double rate = Double.parseDouble("3.75");
        System.out.println(rate * 2);
    }
}
Output
428
50
7.5

If the text is not a valid number, parseInt throws a NumberFormatException:

Java
public class Main {
    public static void main(String[] args) {
        try {
            int n = Integer.parseInt("12kg");
            System.out.println(n);
        } catch (NumberFormatException e) {
            System.out.println("Not a whole number: " + e.getMessage());
        }
    }
}
Output
Not a whole number: For input string: "12kg"

Unlike some languages, parseInt does not stop at the first non-digit; the whole string must be a valid number (surrounding spaces are not allowed either, so call trim() first). You will learn try/catch in Exceptions.

Numbers to strings#

Java
public class Main {
    public static void main(String[] args) {
        int age = 21;
        String s1 = String.valueOf(age);
        String s2 = Integer.toString(age);
        String s3 = "" + age;                      // works, but less clear
        String s4 = String.format("%05d", age);    // with formatting

        System.out.println(s1 + s2 + s3 + " " + s4);
    }
}
Output
212121 00021

char and digits#

A digit character is not its numeric value: '7' has the code 55. Use Character.getNumericValue or subtract '0':

Java
public class Main {
    public static void main(String[] args) {
        char c = '7';
        System.out.println(c - '0');
        System.out.println(Character.getNumericValue(c) * 2);
    }
}
Output
7
14

Common mistakes#

Practice#

Practice exercise

A runner covered 21 km in 125 minutes. Calculate the speed in km/h, print it rounded to the nearest whole number, and also print it with two decimal places.

Show solution
Java
public class Speed {
    public static void main(String[] args) {
        int km = 21;
        int minutes = 125;

        double speed = km / (minutes / 60.0);
        long rounded = Math.round(speed);

        System.out.println(rounded + " km/h");
        System.out.printf("%.2f km/h%n", speed);
    }
}
Output
10 km/h
10.08 km/h

minutes / 60.0 is a floating-point division because 60.0 is a double.

Key takeaway#

Finished this lesson?