Java Type Casting

In the last lesson you learned about Java literals. Sometimes you have a whole number but a calculation needs a decimal, or the other way round. You need to turn one type into another. That move is called type casting.

๐Ÿค” Why do we need casting?

Java is strict about types, so moving a value from one type to another is a controlled step you do on purpose. Think of pouring water: small cup into a big jug is safe, full jug into a small cup overflows.

Everyday cases:

  • Mixing numbers. Divide two whole numbers but want a decimal answer.
  • Trimming a decimal. Keep the whole part of a price like 19.99.
  • Reading data. A value arrives as one type and you need another, like a long stored as an int.
  • Comparing letters. A char is a number inside, so casting to int shows its position.

๐Ÿ” The two kinds of casting

The difference is all about size:

  • Widening goes small to big, like int into double. The value fits, so Java does it automatically and loses nothing.
  • Narrowing goes big to small, like double into int. The value may not fit, so you do it by hand and data may be lost.

The ladder of number types, smallest to biggest. Each step up holds more.

Type Size in bits Holds
byte 8 Small whole numbers
short 16 Medium whole numbers
int 32 Normal whole numbers
long 64 Very large whole numbers
float 32 Decimals, less precise
double 64 Decimals, more precise

Going up is widening. Going down is narrowing.

โฌ†๏ธ Widening: the automatic one

Widening goes small to big, so Java handles it for you. Also called implicit casting.

  • The value always fits, so nothing is lost.
  • You write no special syntax.
  • Safe path: byte โ†’ short โ†’ int โ†’ long โ†’ float โ†’ double.

Here an int flows into a double with no effort from you.

int whole = 10;
double decimal = whole; // โœ… int automatically becomes double
System.out.println(decimal);

Java stores the int 10 in a double box as 10.0. It fits perfectly, so nothing is lost.

Output

10.0

This works mid-calculation too. Add an int and a double together.

int count = 3;
double price = 2.5;
double total = count + price; // โœ… int widens to double, then they add
System.out.println(total);

Java cannot add two different types directly, so it quietly widens the int 3 to 3.0, then adds 3.0 + 2.5 to get 5.5. You did not ask for the cast; Java did it because it was safe.

Output

5.5

โฌ‡๏ธ Narrowing: the manual one

Narrowing goes big to small, where the value might not fit. Also called explicit casting.

  • Java refuses to do it silently.
  • You write the target type in brackets in front of the value.
  • That cast is your signal that you accept the risk.

Here a double is cast down to an int.

double price = 19.99;
int wholePart = (int) price; // โœ… you must write (int)
System.out.println(wholePart);

The (int) forces the double into an int. Java keeps the whole part and drops everything after the dot, so 19.99 becomes 19. It does not round; it cuts the tail off. This is called truncation.

Output

19

Why Java makes narrowing deliberate:

  • A double can hold values an int cannot, like 19.99 or a huge number.
  • Forcing that into an int drops the decimal or wraps a big number around.
  • Java will not throw away your data quietly, so the cast is your signature on the decision.

Narrowing can lose data

When you narrow, Java throws away whatever does not fit. (int) 19.99 becomes 19, not 20. The .99 is gone for good. So only narrow when you actually want to drop that extra part.

๐Ÿ’ฅ When a big number does not fit

Narrowing a number too big for the small type causes overflow: the value wraps around to something strange. A byte only holds -128 to 127. Watch what happens with a bigger number.

int big = 200;
byte small = (byte) big; // โŒ 200 does not fit in a byte
System.out.println(small);

The cast is valid, so Java does not crash. But 200 is past the byte limit of 127, so it wraps past the top and lands on the negative side: you get -56. The overflow is silent, with no warning.

Output

-56

A cast does not promise a sensible answer. It only squeezes the value into the smaller type. So before you narrow, check that the value really fits.

๐Ÿ”ค Casting between char and int

A char is a small number that stands for a letter, using Unicode codes:

  • 'A' is 65, 'B' is 66, and so on.
  • Lowercase 'a' is 97.

Cast a char to an int to see its code.

char letter = 'A';
int code = letter; // โœ… char widens to int automatically
System.out.println(code);

char to int is widening, so Java does it for free. The letter 'A' reveals its code 65.

Output

65

The other way needs an explicit cast, because int is bigger than char. Cast an int into a char to get the letter at that code.

int code = 97;
char letter = (char) code; // โœ… explicit cast int to char
System.out.println(letter);

Code 97 maps to lowercase 'a', so this prints the letter, not the number.

Output

a

This is how you do letter maths. For the next letter, add one to the code, then cast back to char.

char current = 'A';
char next = (char) (current + 1); // โœ… move one step in the alphabet
System.out.println(next);

current + 1 widens 'A' to 65, adds 1 to get 66, and (char) turns 66 back into 'B'. The brackets matter: the cast must wrap the whole sum, not just current.

Output

B

๐Ÿงฎ A real example: integer division

A classic trap: dividing two int values gives an int answer and throws away the decimal.

int total = 7;
int people = 2;
double share = total / people; // โŒ still does int division first
System.out.println(share);

You might expect 3.5. But both are int, so Java divides as whole numbers first to get 3, then stores it in the double. You get 3.0. The decimal was lost before the double got involved.

Output

3.0

The fix: cast one value to double before the division.

int total = 7;
int people = 2;
double share = (double) total / people; // โœ… now it is decimal division
System.out.println(share);

Casting total to double makes the division decimal. Java sees one double, widens the other side too, and divides with decimals. Now you get the answer you wanted.

Output

3.5

You only need to cast one side. As soon as one value is a double, Java widens the other, so total / (double) people works just as well.

โš ๏ธ Common Mistakes

Watch for these traps.

Expecting narrowing to happen automatically. Java will not silently shrink a value. You must write the cast in brackets.

// โŒ Avoid: Java refuses to narrow on its own, this will not compile
int x = 19.99;
// โœ… Good: cast it on purpose
int x = (int) 19.99;

Thinking a cast rounds. Casting a double to int cuts off the decimal, it does not round.

// โŒ Wrong belief: this is 10
int wrong = (int) 9.99; // really 9, the .99 is dropped
// โœ… If you want rounding, use Math.round
long rounded = Math.round(9.99); // this is 10

Casting too late in a division. To get a decimal result from int division, cast before you divide, not after.

// โŒ Avoid: 7 / 2 runs first and gives 3, so this is 3.0
double bad = (double) (7 / 2);
// โœ… Good: cast a value first, so the division itself is decimal
double good = (double) 7 / 2; // 3.5

Forgetting the value might overflow. A cast does not check if the number fits. Casting a big int into a byte or short can wrap around. Check the value is inside the small typeโ€™s range before you narrow.

โœ… Best Practices

Habits that keep casting safe:

  • Prefer widening. Small to big is always safe and never loses data.
  • Narrow only when you mean it. Cast down only when you want to drop the extra part or know the value fits.
  • Cast early in calculations. For decimal math from whole numbers, cast to double before the operation, not after.
  • Use Math.round for rounding. A cast cuts the decimal off; Math.round turns 9.99 into 10.
  • Check the range before narrowing. Otherwise it overflows silently.

๐Ÿงฉ What Youโ€™ve Learned

A quick recap of casting:

  • โœ… Type casting converts a value from one type to another.
  • โœ… Widening (small to big, like int to double) is automatic and loses no data.
  • โœ… Narrowing (big to small, like double to int) is manual: you write (int) in front, and data can be lost.
  • โœ… Casting a double to int cuts off the decimal, it does not round.
  • โœ… Narrowing a number that is too big causes silent overflow, like (byte) 200 giving -56.
  • โœ… A char is a number inside, so you can cast between char and int to do letter maths.
  • โœ… For decimal results from int division, cast one value to double before dividing.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    Which casting does Java do automatically?

    Why: Widening (small type into a bigger one) is safe, so Java does it for you with no special syntax.

  2. 2

    What does (int) 19.99 give you?

    Why: Casting a double to int cuts off the decimal part, so 19.99 becomes 19. It does not round.

  3. 3

    Why must you write (int) when going from double to int?

    Why: Narrowing can lose data, so Java requires an explicit cast to confirm you intend it.

  4. 4

    With int total = 7 and int people = 2, how do you get 3.5 from total / people?

    Why: Casting total to double before dividing makes it decimal division, giving 3.5.

๐Ÿš€ Whatโ€™s Next?

You can convert between types now. Next, see how Java automatically promotes smaller types to bigger ones during calculations, and the rules that decide the result type.

Java Type Promotion

Share & Connect