Java Widening and Narrowing Type Conversion

Steve Pesce
3 min readDec 7, 2020

Since Java is strongly typed, you will often need to convert one type to another. The Java Language Specifications states that there are 13 such conversions possible. Here I will focus on two of these, widening and narrowing type conversions.

While some type conversions need to be deliberately stated, sometimes you may not even notice that you have converted a type. Consider the following example:

Without any extra syntax, x (of type integer) is converted to a double when defining result. This is called Widening Type Casting.

Smaller data types can be converted to larger data types automatically. A more accurate description would be that any type a can be converted to type b if type b is able to represent every value in type a . The data types size goes in the following order (note that char can be represented by its unicode number):

double > float > long > int > char = short > byte

Note that char is a special case here, and I will explain during the next section why short to char is not a widening conversion.

So we can keep converting to the next largest datatype as seen in this example:

As mentioned before, both going from a char to a short and from a short to a char is not widening. A char cannot represent negative values, it can only represent the numbers 0 to 65535 . A short, on the other hand, can only represent numbers from -32768 to 32767.

As you may expect, if you try to convert -100 to a char, you will get unexpected results (it will be the two’s compliment of the number). Similarly, attempting to convert a char with a value of40000 , you will also get unexpected results.

Narrowing Type Casting is when we convert the type of a primitive value to a type that cannot represent every value from the original.

Since we as programmers want to know if we are doing something that may be dangerous, Java will not automatically do these conversions for us — we need to do them manually. Narrowing casting can be done by putting the type in parenthesis immediately before the value.

If we use our previous example and work backwards, we can use narrowing type casting and we still will end up with the same value. We are not losing any information, because the double y has a value of 4 , which can be represented as every one of the types used, down to byte.

However, if we start with a number that we know cant be represented in the type that we are casting to, we get very unreliable results.

---- Output ------
As Double: 1.7976931348623157E308
As Float: Infinity
As Long: 9223372036854775807
As Int: -1
As Short: -1
As Byte: -1
Process finished with exit code 0

Sometimes we dont need the precision that we have, and only want to deal with the whole number. Casting a doubleto an int is the easiest way to trim decimals off of a number, and here we get the result that we expected:

---- Output ------
double: 56.521
int: 56
Process finished with exit code 0

--

--