Java Type Casting
Table of Contents + โ
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
longstored as anint. - Comparing letters. A
charis a number inside, so casting tointshows its position.
๐ The two kinds of casting
The difference is all about size:
- Widening goes small to big, like
intintodouble. The value fits, so Java does it automatically and loses nothing. - Narrowing goes big to small, like
doubleintoint. 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 doubleSystem.out.println(decimal);Java stores the int 10 in a double box as 10.0. It fits perfectly, so nothing is lost.
Output
10.0This 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 addSystem.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
19Why Java makes narrowing deliberate:
- A
doublecan hold values anintcannot, like19.99or a huge number. - Forcing that into an
intdrops 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 byteSystem.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
-56A 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'is65,'B'is66, and so on.- Lowercase
'a'is97.
Cast a char to an int to see its code.
char letter = 'A';int code = letter; // โ
char widens to int automaticallySystem.out.println(code);char to int is widening, so Java does it for free. The letter 'A' reveals its code 65.
Output
65The 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 charSystem.out.println(letter);Code 97 maps to lowercase 'a', so this prints the letter, not the number.
Output
aThis 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 alphabetSystem.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 firstSystem.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.0The fix: cast one value to double before the division.
int total = 7;int people = 2;double share = (double) total / people; // โ
now it is decimal divisionSystem.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.5You 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 compileint x = 19.99;
// โ
Good: cast it on purposeint 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 10int wrong = (int) 9.99; // really 9, the .99 is dropped
// โ
If you want rounding, use Math.roundlong rounded = Math.round(9.99); // this is 10Casting 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.0double bad = (double) (7 / 2);
// โ
Good: cast a value first, so the division itself is decimaldouble good = (double) 7 / 2; // 3.5Forgetting 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
doublebefore the operation, not after. - Use
Math.roundfor rounding. A cast cuts the decimal off;Math.roundturns9.99into10. - 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
inttodouble) is automatic and loses no data. - โ
Narrowing (big to small, like
doubletoint) is manual: you write(int)in front, and data can be lost. - โ
Casting a
doubletointcuts off the decimal, it does not round. - โ
Narrowing a number that is too big causes silent overflow, like
(byte) 200giving-56. - โ
A
charis a number inside, so you can cast betweencharandintto do letter maths. - โ
For decimal results from
intdivision, cast one value todoublebefore dividing.
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 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
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
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
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.