Õppetund 13/140
Kirjalik õppetund · 14 min

Type Conversion and Casting

Convert between types with widening and narrowing conversions and explicit casts, parse numbers from String values and avoid data loss.

Eelvaade

Vaatad tasuta eelvaate õppetundi.

Lesson Overview

Values in a program rarely all have the same type. An int count is added to a long total, a double price must become a whole number, the text "30" typed by a user must become the number 30, and numbers must become text for output.

Changing a value from one type to another is called type conversion. Java performs some conversions automatically and asks us to request others explicitly. The explicit ones are where data is lost and bugs hide, so this lesson shows when Java protects you and when it trusts you.

Learning Objectives

After completing this lesson, you will be able to:

  • Explain type conversion
  • Distinguish between widening and narrowing conversion
  • Understand automatic numeric conversion
  • Write explicit casts
  • Convert decimal values to integers
  • Understand the possibility of data loss
  • Apply casts at the correct point in a calculation
  • Convert between char and integer values
  • Parse numbers from Strings
  • Convert primitive values to String

What Is Type Conversion?

Type conversion means changing a value from one data type to another. In Java, we will mainly look at two types of conversion:

  1. Implicit conversion
  2. Explicit conversion

Implicit Conversion

When Java performs a compatible type conversion automatically, it is called implicit conversion. No cast was required here, because Java automatically converted the int value to long:

java
int value = 100;
long largerValue = value;

Explicit Conversion

When the developer explicitly specifies the target type and requests a conversion, it is called explicit conversion. Here, (int) is a cast, and wholeValue is 99 because the decimal part is lost:

java
double value = 99.75;
int wholeValue = (int) value;

Widening Conversion

Conversion from a smaller numeric type to a wider compatible type is called widening conversion. Simplified order:

Diagrammi joonistamine…

These conversions are generally automatic:

java
byte score = 100;
int expandedScore = score;
int studentCount = 50_000;
long totalStudentCount = studentCount;

Why Is Widening Automatic?

A wider type can generally accommodate the range of a smaller type. For example, a byte holds -128 to 127, and all of these values fit inside an int, so no information can be lost and Java does not need to ask.

Narrowing Conversion and Casting

Conversion from a wider type to a smaller type, such as double to int, is called narrowing conversion. During narrowing:

  • The decimal part may be lost
  • The value may be outside the target type's range
  • Precision may be lost

For this reason, an explicit cast is required.

Casting Syntax

The syntax is (targetType) value. In this example, the target type is int and the source type is double:

java
double average = 85.75;
int wholeAverage = (int) average;

Narrowing Without a Cast

Invalid:

java
double price = 99.75;
int wholePrice = price;

Correct:

java
int wholePrice = (int) price;

In short: integer to decimal is automatic (int 90 becomes 90.0), and decimal to integer needs a cast ((int) 90.75 is 90).

Casting Does Not Round

Casting does not choose the nearest integer. The decimal part is simply discarded, so (int) 99.99 is 99. For a negative value the result is -99, not -100: the conversion moves toward zero. Discarding the decimal part is called truncation:

text
99.99   → 99
99.10   → 99
-99.99  → -99
-99.10  → -99

Narrowing Is Not Always Safe

java
int value = 130;
byte result = (byte) value;
System.out.println(result);

Output:

text
-126

because 130 is outside the byte range. Important:

A cast tells the compiler to allow the conversion. It does not guarantee that the result will be logically correct.

Type Conversion Inside Expressions

When operands have different numeric types, Java can use a wider compatible type for the expression. Here, total is 298.5, because the expression contains a double:

java
int quantity = 3;
double price = 99.50;
double total = quantity * price;

Small Integer Arithmetic

Arithmetic involving byte and short is evaluated as int. This is valid:

java
byte firstValue = 10;
byte secondValue = 20;
int total = firstValue + secondValue;

But byte total = firstValue + secondValue; will not compile because the expression result is int.

Cast Position Matters

Suppose int total = 5; and int count = 2;. Wrong:

java
double average = (double) (total / count);

The division happens first, so the fractional part has already been lost:

text
5 / 2 → 2
(double) 2 → 2.0

Cast Before Division

Correct:

java
double average = (double) total / count;

Now total is converted first, and the result is 2.5:

text
(double) total → 5.0
5.0 / 2 → 2.5

Cast Before or After the Expression?

(int) 10.75 + 5 and (int) (10.75 + 5.50) are not the same. The first casts only 10.75, then adds, giving 15:

text
10.75 → 10
10 + 5 = 15

The second adds first, then casts the sum, giving 16:

text
10.75 + 5.50 = 16.25
16.25 → 16

Parentheses make the target of the cast clear.

Conversion Before Arithmetic Overflow

Look at this code:

java
int price = 2_000_000_000;
int quantity = 2;
long total = price * quantity;

price * quantity is evaluated using int arithmetic first. The result, 4_000_000_000, does not fit in an int, so it overflows before it is stored in total. Safer:

java
long total = (long) price * quantity;

Now price is converted to long first, so the multiplication uses long arithmetic.

char and Numeric Conversion

A char represents a UTF-16 code unit, so it has a numeric value:

java
char letter = 'A';
int code = letter;
char fromCode = (char) 65;
char nextLetter = (char) (letter + 1);
char digitCharacter = '7';
int digitCode = digitCharacter;
System.out.println(code);
System.out.println(fromCode);
System.out.println(nextLetter);
System.out.println(digitCode);

Output:

text
65
A
B
55
  • Conversion from char to int is automatic.
  • Converting a numeric value to char requires an explicit cast.
  • letter + 1 produces an int result, so it is cast back to char.
  • A digit character and a number are not the same: 55 is not numeric 7. It is the code value of the '7' character.

String to Number Conversion

External input may often arrive as text, such as String ageText = "30";. To use it in a numeric calculation, it must be parsed, as in int age = Integer.parseInt(ageText);:

java
String quantityText = "3";
int quantity = Integer.parseInt(quantityText);
int total = quantity * 500;
System.out.println(total);

Output:

text
1500

String to long and double

java
String populationText = "8000000000";
long population = Long.parseLong(populationText);
String priceText = "99.50";
double price = Double.parseDouble(priceText);

String to boolean

Here, active is true:

java
String activeText = "true";
boolean active = Boolean.parseBoolean(activeText);

Boolean.parseBoolean() recognizes "true" case-insensitively, so Boolean.parseBoolean("TRUE") also returns true. Other text, such as Boolean.parseBoolean("yes"), returns false.

Parsing and Casting Are Not the Same

Casting:

java
double value = 10.5;
int result = (int) value;

Parsing:

java
String value = "10";
int result = Integer.parseInt(value);

Difference:

  • Casting converts a value between compatible types
  • Parsing interprets text and creates a new typed value

String Cannot Be Directly Cast to a Number

Invalid:

java
String ageText = "30";
int age = (int) ageText;

Correct:

java
int age = Integer.parseInt(ageText);

Invalid Numeric Text

"thirty" is not a valid integer representation, so this will cause a NumberFormatException at runtime:

java
String ageText = "thirty";
int age = Integer.parseInt(ageText);

Normalize Whitespace Before Parsing

For the input String ageText = " 30 ";, remove surrounding whitespace before parsing:

java
int age = Integer.parseInt(ageText.strip());

Decimal Text Cannot Be Parsed Directly as an Integer

Invalid:

java
String valueText = "10.5";
int value = Integer.parseInt(valueText);

This compiles, but it causes a NumberFormatException at runtime because "10.5" is not a valid integer. Correct:

java
double value = Double.parseDouble(valueText);

Then, if needed:

java
int wholeValue = (int) value;

Number to String Conversion

To convert a primitive value to text, you can use String.valueOf():

java
int age = 30;
String ageText = String.valueOf(age);
String priceText = String.valueOf(99.50);
String activeText = String.valueOf(true);
String gradeText = String.valueOf('A');

Automatic String Conversion During Concatenation

Java uses the text representation of the age value, so message holds Age: 30:

java
int age = 30;
String message = "Age: " + age;

boolean Is Not a Numeric Type

Invalid:

java
boolean active = true;
int value = (int) active;

Similarly, this is not valid:

java
int value = 1;
boolean active = (boolean) value;

In Java, true/false and numeric 1/0 belong to different parts of the type system.

Complete Examples

User Input Conversion

java
public class Main {

    public static void main(String[] args) {
        String ageInput = "30";
        String scoreInput = "85.5";
        String activeInput = "true";

        int age = Integer.parseInt(ageInput);
        double score = Double.parseDouble(scoreInput);
        boolean active = Boolean.parseBoolean(activeInput);

        System.out.println("Age next year: " + (age + 1));
        System.out.println("Score: " + score);
        System.out.println("Active: " + active);
    }
}

Output:

text
Age next year: 31
Score: 85.5
Active: true

Average Calculation

java
public class Main {

    public static void main(String[] args) {
        int totalMarks = 250;
        int subjectCount = 3;

        double average = (double) totalMarks / subjectCount;

        System.out.println("Average: " + average);
    }
}

Output:

text
Average: 83.33333333333333

Conversion Guide

RequirementApproach
int → longAutomatic widening
int → doubleAutomatic widening
double → intExplicit cast
char → intAutomatic widening
int → charExplicit cast
String → intInteger.parseInt()
String → longLong.parseLong()
String → doubleDouble.parseDouble()
String → booleanBoolean.parseBoolean()
Primitive → StringString.valueOf()

Predict the Result

Question 1

java
double firstResult = (double) (5 / 2);
double secondResult = (double) 5 / 2;
System.out.println(firstResult);
System.out.println(secondResult);

What does this print?

Answer

text
2.0
2.5

In the first line the parentheses make the integer division 5 / 2 happen first, giving 2, and only that result becomes 2.0. In the second line 5 becomes 5.0 before the division, so the division is decimal.

Question 2

java
double ratio = 1 / 4;
System.out.println(ratio);

What does this print?

Answer

0.0. Both operands are int, so 1 / 4 is integer division and gives 0. Storing it in a double happens afterwards and only widens 0 to 0.0.

Question 3

java
System.out.println((int) 99.99);
System.out.println((int) 99.01);
System.out.println((int) -99.99);
System.out.println((int) -99.01);

What does this print?

Answer

text
99
99
-99
-99

A cast to int does not round: it removes the decimal part, moving towards zero. Negative values therefore become -99, not -100.

Question 4

java
char letter = 'C';
System.out.println(letter + 1);

What does this print?

Answer

68. In arithmetic a char is promoted to int, and the code of 'C' is 67. To get the letter D, cast the result back: (char) (letter + 1).

Question 5

java
int value = (int) "25";

Will it compile?

Answer

No: incompatible types: String cannot be converted to int. A cast cannot turn text into a number. Parse it instead with Integer.parseInt("25").

Common Mistakes

Casting Too Late

(double) (5 / 2) gives 2.0, because the cast only widens the result of an integer division that has already lost its fraction. Cast an operand instead: (double) 5 / 2 gives 2.5 (see Cast Position Matters above).

Wrong Parser for a Large Value

Wrong:

java
int population = Integer.parseInt("8000000000");

The value is outside the int range, so this causes a NumberFormatException at runtime. Use:

java
long population = Long.parseLong("8000000000");

Direct Number-to-String Cast

Invalid:

java
int age = 30;
String ageText = (String) age;

Correct:

java
String ageText = String.valueOf(age);

Practice Exercise 1: Widening or Narrowing?

Solutions: lesson 1.24.

Classify each conversion:

  1. byte → int
  2. int → long
  3. long → int
  4. float → double
  5. double → int
  6. char → int
  7. int → char

Practice Exercise 2: Fix the Average

Use casting to produce a decimal average. Wrong:

java
int totalMarks = 250;
int subjectCount = 3;
double average = totalMarks / subjectCount;

Practice Exercise 3: Character Conversion

For char letter = 'A';, do the following:

  1. Get the integer code from the char
  2. Create a char from integer 66

Practice Exercise 4: Parse Values

Parse each value into the appropriate type:

java
String ageText = "30";
String populationText = "8000000000";
String scoreText = "85.5";
String activeText = "true";

Practice Exercise 5: Normalize Before Parsing

Use strip() and parse this text to int, then multiply the result by 2:

java
String quantityText = "   5   ";

Expected output:

text
10

Practice Exercise 6: Convert to String

Convert the following values to String using String.valueOf():

java
int age = 30;
double score = 85.5;
boolean active = true;
char grade = 'A';

Knowledge Check

Question 1

What is type conversion?

Question 2

What is implicit conversion?

Question 3

What is explicit conversion?

Question 4

What is widening conversion?

Question 5

What is narrowing conversion?

Question 6

What is the casting syntax?

Question 7

Does converting int to long require a cast?

Question 8

Does converting double to int require a cast?

Question 9

What is the result of (int) 99.99?

Question 10

Does casting perform rounding?

Question 11

Why is it important to cast before division?

Question 12

Is conversion from char to int automatic?

Question 13

What is required to convert int to char?

Question 14

Which method parses a String into an int?

Question 15

Which method parses a String into a long?

Question 16

Which method parses a String into a double?

Question 17

What general method converts a primitive value to String?

Question 18

What can happen when invalid numeric text is parsed?

Question 19

Can a boolean be cast to a numeric type?

Question 20

Are casting and parsing the same?

Knowledge Check Answers

Answer 1

Changing a value from one data type to another is called type conversion.

Answer 2

When Java performs a conversion automatically, it is called implicit conversion.

Answer 3

When the developer explicitly uses a cast or conversion method, it is called explicit conversion.

Answer 4

Conversion from a smaller compatible type to a wider type is called widening conversion.

Answer 5

Conversion from a wider type to a smaller type is called narrowing conversion.

Answer 6

(targetType) value

Answer 7

No. This is generally an automatic widening conversion.

Answer 8

Yes, as in int value = (int) doubleValue;.

Answer 9

99

Answer 10

No. It truncates the decimal part.

Answer 11

If integer division happens first, the fractional part is lost. Therefore, if a decimal result is required, one operand must be converted to floating-point before the division occurs.

Answer 12

Yes.

Answer 13

An explicit cast, such as (char) 65.

Answer 14

Integer.parseInt()

Answer 15

Long.parseLong()

Answer 16

Double.parseDouble()

Answer 17

String.valueOf()

Answer 18

A NumberFormatException can occur.

Answer 19

No.

Answer 20

No. Casting converts compatible typed values. Parsing interprets text and creates a typed value.

Lesson Summary

  • Type conversion changes a value from one data type to another.
  • Widening conversions, such as int to long or int to double, happen automatically.
  • Narrowing conversions, such as double to int, need an explicit cast: (targetType) value.
  • A cast to an integer type truncates toward zero. It does not round.
  • A cast does not make an out-of-range value safe: (byte) 130 is -126.
  • Cast before division or multiplication when you need a decimal result or a wider type.
  • Parse text with Integer.parseInt(), Long.parseLong(), Double.parseDouble() and Boolean.parseBoolean(). Invalid numeric text causes a NumberFormatException.
  • Convert a primitive value to text with String.valueOf() or String concatenation.

Mõtle enne

Tulekul

Kontrollküsimused, mille puhul valid vastuse enne, kui õppetund selle näitab.