1. Implicit (automatic) type casting
In Java (as in other languages) variables have a strict type—if a variable is declared as int, it can store only integers, and if as double—only floating-point numbers. But in real programs, you often need to “move” a value from one variable to another of a different type. For example:
- We received an int from a method, but want to use it as a double for fractional calculations.
- We store a character code as a number (int) and want to get the character itself (char).
- There is a computation result in double, but we need an integer result (int), for example, to print the number of whole apples.
Java has two main ways to convert types: implicit (automatic) and explicit (manual).
What is it?
Implicit casting is when Java automatically, “without your participation,” converts a value from one type to another if it is safe and does not lead to data loss.
This happens when you assign a value of a smaller type to a variable of a larger type. For example, from int to double, from char to int, from float to double.
Analogy: Imagine you have a glass of water (int) and a bucket (double). If you pour water from the glass into the bucket—nothing spills, everything fits. Java allows automatic conversion in such cases.
Example: int → double
int apples = 5;
double applesWeight = apples; // int automatically becomes double
System.out.println(applesWeight); // 5.0
Example: char → int
Every character in Java is just a number from the Unicode table. Therefore, converting char to int happens automatically:
char letter = 'A';
int code = letter; // 'A' converts to 65 (character code in Unicode)
System.out.println(code); // 65
Table of implicit conversions
| From | Implicitly to |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Important: Implicit conversion works only in the direction of “widening” (from smaller to larger).
2. Explicit (manual) type casting
Explicit casting is required when you want to convert a value from a larger type to a smaller one or between incompatible types. In this case, Java requires you to explicitly indicate that you are aware of possible data loss.
Analogy: You try to pour water from a bucket (double) into a glass (int)—some water may spill, and Java requires you to say: “Yes, I understand that some data may be lost!”
Syntax
target_type variable = (target_type) expression;
Example: double → int
double price = 12.99;
int roundedPrice = (int) price; // the fractional part is simply discarded!
System.out.println(roundedPrice); // 12
Warning: No rounding occurs! You just “cut off” everything after the decimal point. For rounding, use Math.round().
Example: int → char
int code = 66;
char letter = (char) code; // 66 is the character 'B'
System.out.println(letter); // B
Example: double → float
double d = 3.1415926535;
float f = (float) d; // part of the precision is lost
System.out.println(f); // 3.1415927 (fewer digits after the decimal point)
3. Conversion between numbers and characters (char and numbers)
Why is this possible?
In Java, characters (char) are actually just numbers from the Unicode table. Therefore, they can be freely converted to int and vice versa.
Example: char → int
char ch = '\u0416';
int code = ch;
System.out.println(code); // 1046
Example: int → char
int code = 8364;
char symbol = (char) code;
System.out.println(symbol); // €
Practice: print the alphabet
for (int i = 65; i < 65 + 26; i++) {
System.out.print((char) i + " ");
}
// Will output: A B C D ... Z
4. Conversion between integers and floating-point numbers
int → double (implicitly)
int count = 10;
double avg = count; // implicit widening
System.out.println(avg); // 10.0
double → int (explicitly)
double score = 8.75;
int rounded = (int) score;
System.out.println(rounded); // 8
How to round mathematically?
If you need not just to “drop” the fractional part but round to the nearest integer, use Math.round():
double price = 8.75;
int rounded = (int) Math.round(price);
System.out.println(rounded); // 9
5. What happens when narrowing a type? Data loss
Example: int → byte
int big = 300;
byte small = (byte) big;
System.out.println(small); // 44 (!)
Why 44? Because byte stores values from -128 to 127, and if a number does not fit, it is “truncated” modulo 256 (remainder of division).
Example: double → int
double d = 1e20;
int i = (int) d;
System.out.println(i); // -2147483648 (minimum int value)
The large number does not fit into the int range, and the result becomes “strange.”
6. Conversion during calculations: “mixed” types
Example: int + double
int a = 3;
double b = 2.5;
double result = a + b; // int will automatically become double
System.out.println(result); // 5.5
Example: char + int
char ch = 'A'; // 65
int offset = 2;
char next = (char) (ch + offset); // char will automatically become int
System.out.println(next); // C
7. Conversion between numbers and strings
Although this isn't exactly “type casting,” you often need to convert a number to a string and back.
int → String
int x = 123;
String s = Integer.toString(x);
// or simply: String s = "" + x;
String → int
String s = "456";
int x = Integer.parseInt(s);
8. Common mistakes and nuances
Error #1: Loss of the fractional part when double → int. Very often beginners think that (int) 3.99 will give 4. In reality the result is 3, the fractional part is simply discarded. For proper rounding use Math.round().
Error #2: Implicit “narrowing” does not work. You can’t just write int x = 300; byte b = x;—the compiler will produce an error. You must explicitly specify (byte) x, but be ready for strange results if the number exceeds the byte range.
Error #3: Conversion between incompatible types. You cannot write (int) "123"—a string must be converted to a number via Integer.parseInt().
Error #4: Issues with char and int. Converting int to char works only for values that actually exist in Unicode. If you pass a large number, the result will be an unexpected character.
Error #5: Mixed types in expressions. If an expression contains int and double, the result will always be double. This may unexpectedly affect program logic if you expect an integer.
Error #6: Rounding is not type casting! (int) x is not rounding, it simply discards the fractional part. For rounding use Math.round().
GO TO FULL VERSION