Type Conversion and Casting in Java with Examples
Introduction
Programs constantly mix types - an
(Note - This tutorial builds on Java Primitive Data TypesClick to read tutorial: Java Primitive Data Types and Their Ranges with Examples, which lists the size and range of each type.) Widening conversion - automatic A widening conversion converts a value to a type which can hold every value of the original type. Java does it automatically, because nothing is lost. The widening order of the numeric types is -
and
OUTPUT of the above code
Explanation of the code
Narrowing conversion - explicit casting
A narrowing conversion goes the other way - from a type to one which cannot hold all of its values, such as
OUTPUT on compiling the above code
To tell the compiler that you accept the loss, write a cast - the target type in parentheses before the value -
OUTPUT of the above code
Explanation of the code
Numeric promotion in expressions
When an expression combines values, Java first converts them to a common type, following these rules of binary numeric promotion -
OUTPUT of the above code
Explanation of the code
OUTPUT of the above code
Explanation of the code
int count multiplied by a double price, or a long timestamp stored in an int. This tutorial explains type conversion and casting in Java. We will start with widening conversions, which Java does automatically. We will then look at narrowing conversions, which need an explicit cast, and see exactly what happens to values that do not fit. Next we will learn the rules of numeric promotion in expressions, which explain several surprising results. Lastly, we will convert between numbers and strings, which is not done by casting at all.(Note - This tutorial builds on Java Primitive Data TypesClick to read tutorial: Java Primitive Data Types and Their Ranges with Examples, which lists the size and range of each type.) Widening conversion - automatic A widening conversion converts a value to a type which can hold every value of the original type. Java does it automatically, because nothing is lost. The widening order of the numeric types is -
byte → short → int → long → float → doublechar can be widened to int and the types after it. Any type in the chain can be assigned to a type further to its right without a cast.
Widening conversions happen automatically
//Widening.java
public class Widening {
public static void main(String[] args) {
int count = 42;
long bigCount = count; // int -> long
double average = count; // int -> double
char letter = 'A';
int code = letter; // char -> int
System.out.println(bigCount + " " + average + " " + code);
long big = 123_456_789_123L;
float f = big; // long -> float: allowed, but may lose precision
System.out.println(big + " as float = " + f);
}
}
42 42.0 65 123456789123 as float = 1.2345679E11
- No casts were needed.
averageprinted as42.0- the value is the same, now stored as adouble. chartointgives the character's Unicode number, 65.- Watch out:
longtofloat(andintorlongtodoublefor very large values) is a widening conversion, but it can lose precision. Afloatkeeps only about 7 significant digits, so123456789123became1.2345679E11- about 123456790000. The range fits; the exact digits do not.
double to int. Because information may be lost, Java will not do it automatically -
Narrowing without a cast does not compile
//NoCast.java
public class NoCast {
public static void main(String[] args) {
double price = 9.99;
int whole = price;
}
}
NoCast.java:5: error: incompatible types: possible lossy conversion from double to int
int whole = price;
^
1 error
int whole = (int) price;Narrowing conversions with casts
//Narrowing.java
public class Narrowing {
public static void main(String[] args) {
double price = 9.99;
System.out.println("(int) 9.99 = " + (int) price);
System.out.println("(int) -9.99 = " + (int) -9.99);
System.out.println("Math.round = " + Math.round(price));
int big = 300;
System.out.println("(byte) 300 = " + (byte) big);
long tooBig = 3_000_000_000L;
System.out.println("(int) 3 billion = " + (int) tooBig);
double huge = 1e20;
System.out.println("(int) 1e20 = " + (int) huge);
int code = 66;
System.out.println("(char) 66 = " + (char) code);
}
}
(int) 9.99 = 9 (int) -9.99 = -9 Math.round = 10 (byte) 300 = 44 (int) 3 billion = -1294967296 (int) 1e20 = 2147483647 (char) 66 = B
- Floating-point to integer: the fractional part is cut off (truncated towards zero), not rounded.
9.99becomes9, and-9.99becomes-9. UseMath.round()to round to the nearest whole number. - Integer to a smaller integer: only the lowest bits are kept, so the value can change completely. 300 does not fit in a
byte(-128 to 127), and becomes 44. 3 billion does not fit in anint, and becomes a negative number. - Floating-point too large for the integer type: the result is the largest (or smallest) value of the target type, so
(int) 1e20givesInteger.MAX_VALUE. (char) 66converts a Unicode number back to its character,B.
Math.toIntExact(), which throws an exception instead of silently changing the value.
- If either value is a
double, the other is converted todouble. - Otherwise, if either is a
float, the other becomesfloat. - Otherwise, if either is a
long, the other becomeslong. - Otherwise, both become
int- even if they are bothbyte,shortorchar.
Numeric promotion in expressions
//Promotion.java
public class Promotion {
public static void main(String[] args) {
int total = 7, count = 2;
System.out.println("7 / 2 = " + (total / count));
System.out.println("7 / 2.0 = " + (total / 2.0));
System.out.println("(double) 7 / 2 = " + ((double) total / count));
System.out.println("(double)(7 / 2)= " + (double) (total / count));
byte a = 10, b = 20;
byte sum = (byte) (a + b); // a + b is an int, so a cast is needed
System.out.println("byte sum = " + sum);
char c = 'A';
System.out.println("'A' + 1 = " + (c + 1));
c += 1; // compound assignment casts automatically
System.out.println("c after += 1 = " + c);
}
}
7 / 2 = 3 7 / 2.0 = 3.5 (double) 7 / 2 = 3.5 (double)(7 / 2)= 3.0 byte sum = 30 'A' + 1 = 66 c after += 1 = B
7 / 2is3: both values areint, so integer division is used and the remainder is dropped. Making either value adouble-7 / 2.0, or casting one value with(double) total / count- gives3.5.(double) (7 / 2)gives3.0, not3.5. The division inside the parentheses happens first, withints, and only its result is cast. Cast a value before the division, not the result after it.a + bis anint, even thoughaandbarebytes, so assigning it to abyteneeds a cast.c + 1is theint66, butc += 1gives thecharB. Compound assignment operators such as+=include a hidden cast back to the variable's type. See assignment operatorsClick to read tutorial: Java Assignment, Increment/Decrement and Ternary Operators for more.
String and a number - (int) "42" does not compile. Use methods of the wrapper classes and String instead.
Converting between strings and numbers
//StringConversion.java
public class StringConversion {
public static void main(String[] args) {
int quantity = Integer.parseInt("42");
double price = Double.parseDouble("19.99");
System.out.println("total = " + quantity * price);
String s1 = String.valueOf(quantity);
String s2 = "" + price;
System.out.println(s1 + " and " + s2 + " are Strings of length " + s1.length() + " and " + s2.length());
int bad = Integer.parseInt("forty-two");
}
}
total = 839.5799999999999 42 and 19.99 are Strings of length 2 and 5 Exception in thread "main" java.lang.NumberFormatException: For input string: "forty-two" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) at java.base/java.lang.Integer.parseInt(Integer.java:564) at java.base/java.lang.Integer.parseInt(Integer.java:661) at StringConversion.main(StringConversion.java:12)
Integer.parseInt()andDouble.parseDouble()convert text to numbers. Each wrapper class has a similar method, such asLong.parseLong(). (The long total,839.5799999999999, is the floating-point rounding error described in primitive data typesClick to read tutorial: Java Primitive Data Types and Their Ranges with Examples.)String.valueOf(), or joining a number to a string with+, converts a number to text.- Text which is not a valid number causes a
NumberFormatExceptionat runtime - so check or handle user input before parsing it.
byte to double, and noted that long to float can lose precision. We then used casts for narrowing conversions, and saw that floating-point values are truncated and that integers which do not fit lose their high bits. Next we learned the rules of numeric promotion, which explain integer division, why byte + byte is an int, and where to put a cast. Lastly, we converted between strings and numbers with parseInt(), parseDouble() and String.valueOf(). In the next tutorial, we will let the compiler work out types for us with the var keywordClick to read tutorial: Java var Keyword: Local Variable Type Inference.Java Fundamentals Tutorials
Java Literals: Integer, Floating-Point, char and booleanClick to read tutorial: Java Literals: Integer, Floating-Point, char and boolean Java var Keyword: Local Variable Type InferenceClick to read tutorial: Java var Keyword: Local Variable Type Inference Java Syntax Basics: Statements, Identifiers, KeywordsClick to read tutorial: Java Syntax Basics: Statements, Identifiers, Keywords Variables in Java: Declaration, Initialization and ScopeClick to read tutorial: Variables in Java: Declaration, Initialization and Scope Java Primitive Data Types and Their Ranges with ExamplesClick to read tutorial: Java Primitive Data Types and Their Ranges with Examples Java Arithmetic, Relational and Logical OperatorsClick to read tutorial: Java Arithmetic, Relational and Logical Operators Java Bitwise and Shift Operators with ExamplesClick to read tutorial: Java Bitwise and Shift Operators with Examples
Java Literals: Integer, Floating-Point, char and booleanClick to read tutorial: Java Literals: Integer, Floating-Point, char and boolean Java var Keyword: Local Variable Type InferenceClick to read tutorial: Java var Keyword: Local Variable Type Inference Java Syntax Basics: Statements, Identifiers, KeywordsClick to read tutorial: Java Syntax Basics: Statements, Identifiers, Keywords Variables in Java: Declaration, Initialization and ScopeClick to read tutorial: Variables in Java: Declaration, Initialization and Scope Java Primitive Data Types and Their Ranges with ExamplesClick to read tutorial: Java Primitive Data Types and Their Ranges with Examples Java Arithmetic, Relational and Logical OperatorsClick to read tutorial: Java Arithmetic, Relational and Logical Operators Java Bitwise and Shift Operators with ExamplesClick to read tutorial: Java Bitwise and Shift Operators with Examples