Type Casting and Type Conversion

Naveen AnamaneniUpdated · 5 min read

Pouring water from a small glass into a big jug is safe; nothing spills. Pouring a full jug into a small glass is risky; some water ends up on the floor. Converting numbers between types works the same way. Going from a smaller type to a bigger one is safe, so Java does it for you. Going from bigger to smaller can lose data, so Java makes you say so explicitly with a cast.

Widening and Narrowing

Widening happens automatically; narrowing needs a cast
Widening (implicit)Narrowing (explicit cast)
DirectionSmaller type → bigger typeBigger type → smaller type
Who does itJava, automaticallyYou, by writing (type)
RiskNone for whole numbersDecimals cut off, or the value wraps around
Exampledouble d = 450;int i = (int) 99.99;

Widening: Automatic

Widening.java▶ Try it
public class Widening {
    public static void main(String[] args) {
        int fare = 450;
        long bigFare = fare;
        double exactFare = fare;
        System.out.println(bigFare + " and " + exactFare);
    }
}
Output
450 and 450.0

Lines 4 and 5 copy an int into a long and a double. Every int value fits in both, so no cast is needed.

Narrowing: You Must Cast

Going the other way without a cast is a compile error:

Compiler output
Narrow.java:4: error: incompatible types: possible lossy conversion from double to int
        int rupees = price;
                     ^

Writing the target type in brackets, a cast, tells the compiler "I know data may be lost":

Narrowing.java▶ Try it
public class Narrowing {
    public static void main(String[] args) {
        double price = 99.99;
        int rupees = (int) price;
        System.out.println("Rupees: " + rupees);
 
        int big = 300;
        byte small = (byte) big;
        System.out.println("300 as a byte: " + small);
 
        long rounded = Math.round(price);
        System.out.println("Rounded: " + rounded);
    }
}
Output
Rupees: 99
300 as a byte: 44
Rounded: 100

How it works

  1. Line 4 casts 99.99 to int. A cast cuts off the decimal part; it does not round. The result is 99.
  2. Line 8 squeezes 300 into a byte, whose range is -128 to 127. Only the lowest 8 bits are kept: 300 − 256 = 44. The value is wrong, and Java gives no warning at runtime.
  3. Line 11 uses Math.round, which rounds to the nearest whole number instead: 100.

Try it yourself: cast -99.99 to int. Is the result -99 or -100?

char and int

A char is a number underneath, so it widens to int automatically, and an int can be cast to char:

Letters.java▶ Try it
public class Letters {
    public static void main(String[] args) {
        int code = 'A';
        char next = (char) (code + 2);
        System.out.println(code + " " + next);
    }
}
Output
65 C

Conversion That Isn't Casting

Turning text into a number, or a number into text, isn't a cast; you call a method:

FromToUse
"450"intInteger.parseInt("450")
"99.5"doubleDouble.parseDouble("99.5")
450StringString.valueOf(450) or "" + 450

(int) "450" doesn't compile: casts only work between numeric types (and between related object types, which Level 2 covers).

Common Mistakes

Expecting a cast to round. (int) 9.99 is 9. Use Math.round to round.

Casting after dividing. (double) (7 / 2) is 3.0, because 7 / 2 is already 3. Cast first: (double) 7 / 2 is 3.5.

Using a cast to "fix" a compile error. If a long doesn't fit in an int, casting hides the bug. Change the variable's type instead.

Interview Corner

What is the difference between widening and narrowing conversion?

Widening converts a smaller numeric type to a larger one, such as int to long or double. Java does it automatically because no information is lost. Narrowing goes from larger to smaller, such as double to int; it needs an explicit cast because decimals can be cut off or the value can overflow.

What is the output of (int) 99.99 and (byte) 300?

(int) 99.99 is 99, because casting to int truncates the decimal part. (byte) 300 is 44, because only the lowest 8 bits are kept and 300 − 256 = 44.

Practice

  1. Easy: Write the result of each without running it: (int) 7.9, (int) -7.9, (long) 2.5, (char) 66.
  2. Harder: A price is 249.75. Print it as whole rupees by cutting off the paise, and again by rounding. Then print the paise part alone as an int (75).

Quick check: Type casting

4 questions
1Which conversion happens automatically?
2What is (int) 99.99?
3What is (byte) 130?
4How do you turn the text "450" into an int?

Key Takeaways

Was this tutorial helpful?

Lesson 38 of 482