Which Primitive Data Types Can Be Type Cast to Which Data Types in Java?

Learn Java primitive type casting and understand which data types can be converted into others. This article explains widening and narrowing conversions, explicit casting, data loss, precision loss, byte overflow, and common casting examples. It also covers real-world scenarios involving money, measurements, large numbers, character codes, and Boolean values to help you understand when type casting is safe and when it can produce unexpected results.

Programming Language Java 📅 Aug 14, 2026 👁️ 59 Views
Written by Rohan Kumar
Which Primitive Data Types Can Be Type Cast to Which Data Types in Java?
Learn Java primitive type casting and understand which data types can be converted into others. This article explains widening and narrowing conversions, explicit casting, data loss, precision loss, byte overflow, and common casting examples. It also covers real-world scenarios involving money, measurements, large numbers, character codes, and Boolean values to help you understand when type casting is safe and when it can produce unexpected results.

Type casting is an important concept in Java because sometimes we need to convert a value from one primitive data type to another.

For example, an int can be converted to a long, while a double can be converted to an int. However, not every primitive data type can be converted to every other primitive data type.

More importantly, some conversions can cause data loss, precision loss, overflow, or unexpected results.

In this article, we will understand:

  • Which primitive data types can be converted to which other types

  • Widening and narrowing conversions

  • Which conversions happen automatically

  • Which conversions require explicit casting

  • Where data loss can occur

  • Why boolean cannot be cast to numeric types

  • Real-world examples of why careless casting can be dangerous


Primitive Data Types in Java

Java has eight primitive data types:

Data Type Size General Purpose
byte 8 bits Small integer
short 16 bits Integer
int 32 bits Integer
long 64 bits Large integer
float 32 bits Decimal number
double 64 bits More precise decimal number
char 16 bits Character / UTF-16 code unit
boolean JVM-dependent true / false

The numeric primitive types can be broadly divided into:

Integral Types:
byte → short → int → long
char

Floating-Point Types:
float → double

Boolean:
boolean

1. Widening Conversion

A widening conversion happens when a value is converted from a type that can represent a smaller range or set of values to a type that can represent it more broadly.

For example:

int a = 100;
long b = a;

Here, the int value is converted to long.

Java can perform this conversion automatically:

int a = 100;
long b = a;

You do not need:

long b = (long) a;

Although explicitly writing the cast is possible, it is normally unnecessary.


2. Widening Conversion Order

For the integer types, the commonly used widening path is:

byte
  ↓
short
  ↓
int
  ↓
long
  ↓
float
  ↓
double

There is also a widening path from char to:

char → int → long → float → double

However, there is an important point:

Widening does not always mean that every possible value can be represented exactly.

For example, converting a very large long to float is allowed, but a float has limited precision. Therefore, some integer values may not remain exactly representable.


3. Widening Conversion Examples

byte → short

byte a = 100;
short b = a;

No explicit cast is required.


byte → int

byte a = 100;
int b = a;

byte → long

byte a = 100;
long b = a;

int → long

int a = 100000;
long b = a;

int → float

int a = 100;
float b = a;

The result will be:

100.0

int → double

int a = 100;
double b = a;

The result will be:

100.0

float → double

float a = 12.5f;
double b = a;

This is also allowed automatically.


4. Narrowing Conversion

Now consider the opposite direction.

Suppose we have:

double price = 99.99;

and we want to store it in an int:

int amount = price;

Java does not allow this automatically.

We have to explicitly tell Java that we want the conversion:

int amount = (int) price;

This is called narrowing conversion or explicit type casting.


5. Primitive Type Casting Chart

A useful way to remember the common primitive conversions is:

From Can Widen To
byte short, int, long, float, double
short int, long, float, double
char int, long, float, double
int long, float, double
long float, double
float double
double
boolean No numeric primitive type

Narrowing conversions can also be explicitly performed in the reverse direction where Java defines the conversion.

For example:

double → float
double → long
double → int
double → short
double → byte

float → long
float → int
float → short
float → byte

long → int
long → short
long → byte

int → short
int → byte

short → byte

And:

int → char
long → char
short → char
byte → char
float → char
double → char

can also be performed using explicit casting where Java permits the conversion.


6. Why Does Java Require Explicit Casting?

Imagine you have a bottle containing:

1 litre

and another container that can hold:

5 litres

Moving 1 litre into the 5-litre container is safe.

But now imagine you have:

5 litres

and try to put it into a:

1 litre

container.

Something has to happen to the extra water.

The same idea applies to narrowing conversions.

For example:

double price = 99.99;
int amount = (int) price;

The int cannot store the .99 fractional portion.

Therefore:

99.99 → 99

The decimal portion is discarded.

Java requires the explicit cast because you are asking it to perform a conversion that may lose information.


7. Data Loss When Converting double to int

Consider:

double price = 99.99;
int amount = (int) price;

System.out.println(amount);

Output:

99

Notice that Java does not round:

99.99 → 100

Instead, the fractional part is truncated:

99.99 → 99

The same happens with:

double value = 99.999;
int result = (int) value;

Result:

99

8. Real-World Example: Money and Prices

This is particularly important when dealing with money.

Suppose an online shopping application calculates:

double price = 999.99;

If you do:

int priceInRupees = (int) price;

you get:

999

You have lost:

₹0.99

That might look small for one transaction, but imagine performing this conversion across thousands or millions of transactions.

Therefore, blindly casting monetary values can create incorrect calculations.

For financial applications, developers generally use BigDecimal rather than relying on floating-point types for exact monetary calculations.


9. Floating-Point Precision Loss

Another important type of loss can happen when converting from an integer type to a floating-point type.

For example:

long value = 9007199254740993L;
double result = value;

System.out.println(result);

This conversion is allowed.

However, double has finite precision. It cannot represent every possible long value exactly.

Therefore, although this is technically a widening conversion, the exact integer value may not survive the conversion.

This gives us an important lesson:

A widening conversion does not necessarily guarantee that the exact numerical value will always be preserved.

This is especially important when dealing with very large integers.


10. Real-World Example: Large IDs

Imagine an application receives a very large identification number:

9007199254740993

If we unnecessarily store it in a double, we risk losing exactness.

For example:

long id = 9007199254740993L;
double convertedId = id;

The double representation cannot distinguish every integer at that magnitude.

This is one reason why identifiers should generally remain integer or String values rather than being converted to floating-point numbers simply because a floating-point type is available.

For IDs, accuracy matters more than whether the number contains a decimal point.


11. Integer Overflow During Narrowing

Data loss is not limited to decimal values.

Consider:

int a = 128;
byte b = (byte) a;

System.out.println(b);

Output:

-128

Why?

A byte can represent only:

-128 to 127

The value 128 is outside that range.

When the int is narrowed to a byte, only the relevant 8-bit representation remains, producing the wrapped result:

128 → -128

12. Another Byte Overflow Example

Consider:

int a = 129;
byte b = (byte) a;

System.out.println(b);

Output:

-127

And:

int a = 130;
byte b = (byte) a;

System.out.println(b);

Output:

-126

The values continue wrapping around the byte range.


13. Large Integer to Byte

Let's take a larger example:

int a = 726;
byte b = (byte) a;

System.out.println(b);

Output:

-42

A byte has 256 possible bit patterns.

We can reduce the value using:

726 mod 256 = 214

Since Java's byte is signed, the 8-bit value 214 corresponds to:

214 - 256 = -42

Therefore:

726 → -42

This is a good example of why narrowing conversions can produce results that look completely unrelated to the original value.


14. Real-World Example: Temperature

Imagine an application stores temperature as:

double temperature = 36.8;

If you cast it directly:

int temperatureValue = (int) temperature;

you get:

36

If the application needs the exact temperature, this is a problem.

For example:

36.8°C

and:

36°C

are not the same measurement.

However, if the application intentionally wants only the whole-number portion for display, the conversion may be acceptable.

The important question is not simply:

"Can I cast this?"

It is:

"Do I actually want to lose the information contained in the original value?"


15. char and Numeric Types

char is another primitive type that can participate in numeric conversions.

For example:

char ch = 'A';
int value = ch;

System.out.println(value);

Output:

65

The character 'A' has the UTF-16 code unit value 65.

Similarly:

int value = 66;
char ch = (char) value;

System.out.println(ch);

Output:

B

So char can participate in numeric conversions.

However, remember that char represents a UTF-16 code unit, not simply a "number that happens to print as a character."


16. Real-World Example: Character Codes

Character-to-number conversion can be useful when working with character codes.

For example:

char grade = 'A';
int code = grade;

Now code contains the numeric code associated with 'A'.

Similarly:

int code = 65;
char character = (char) code;

produces:

A

This concept becomes useful when learning about character encoding and text processing.


17. boolean Cannot Be Cast to Numeric Types

One important exception is boolean.

You cannot do this:

boolean value = true;
int number = (int) value;

This is invalid Java.

Java does not treat:

true → 1
false → 0

as an implicit or explicit primitive numeric conversion.

This is different from some other programming languages.

If an application needs such a representation, you must explicitly define the logic yourself:

boolean isLoggedIn = true;

int status = isLoggedIn ? 1 : 0;

Now:

true → 1
false → 0

But this is not type casting. It is a conditional expression that you have written.


18. Real-World Example: Login Status

Suppose a system has:

boolean isLoggedIn = true;

You might want to send:

1 → logged in
0 → logged out

You cannot write:

int status = (int) isLoggedIn;

Instead:

int status = isLoggedIn ? 1 : 0;

This explicitly defines how the application's Boolean state should be represented numerically.


19. Which Conversions Should You Be Careful About?

The following conversions deserve extra attention:

double → int

Potential loss of:

  • Decimal portion

  • Precision required by the application

double value = 99.99;
int result = (int) value;

Result:

99

float → int

The fractional portion is discarded.

float value = 34.632f;
int result = (int) value;

Result:

34

long → int

Large values can fall outside the int range.

long value = 3000000000L;
int result = (int) value;

The result will not be 3000000000 because an int cannot represent that value.


int → byte

Values outside:

-128 to 127

can wrap around.

int value = 128;
byte result = (byte) value;

Result:

-128

long → float

The conversion is allowed, but the float may not be able to represent the original integer exactly.


double → float

The range and precision are reduced, so the resulting float may lose precision or become infinite for sufficiently large values.


20. A Simple Rule to Remember

When deciding whether a conversion is safe, ask two questions:

Question 1: Can the destination type represent the original range?

For example:

int → long

is generally safe in terms of integer range.

But:

long → int

can lose information because int has a smaller range.

Question 2: Can the destination type preserve the required precision?

For example:

double → int

loses the fractional part.

And:

long → float

may lose integer precision for sufficiently large values.


21. Quick Conversion Reference

A simplified reference for Java primitive conversions is:

byte
  ↓
short
  ↓
int
  ↓
long
  ↓
float
  ↓
double

And:

char → int → long → float → double

These are the main widening directions.

For narrowing, explicit casting can be used for compatible primitive conversions, for example:

double → float
double → long
double → int
double → short
double → byte

float → long
float → int
float → short
float → byte

long → int
long → short
long → byte

int → short
int → byte

char can also be involved in explicit numeric narrowing conversions.

boolean is separate and cannot be cast to or from numeric primitive types.


22. Final Takeaways

Type casting is more than simply putting a type inside parentheses.

Whenever you cast one primitive type into another, you should think about what information might be lost.

For example:

double price = 99.99;
int value = (int) price;

results in:

99

because the decimal portion is discarded.

Similarly:

int value = 128;
byte result = (byte) value;

results in:

-128

because the value is outside the range that a byte can represent.

And even a widening conversion such as:

long value = 9007199254740993L;
double result = value;

can lose exact integer precision because double has finite precision.

Therefore, the best rule is:

Never perform a type conversion just because Java allows it. First ask whether the destination type can represent the value with the range and precision your application requires.

Understanding this will help you avoid subtle bugs in calculations, financial applications, measurements, IDs, counters, and other real-world Java programs.

🔖 Bookmark saved successfully!