In Java 21, it is possible to cast objects to different types. A type is often considered part of the data: it is metadata, information about itself.
Casting and converting in Java is a practical operation. We use implicit (hidden) and explicit (specified) casts. Complex conversions too are needed.
This program casts a String
variable to its ancestor class
Object (all classes derive from Object). It then casts the object back to a String
.
String
in the third statement.instanceof
operator expression. This code will not throw an exception if the cast is invalid.public class Program { public static void main(String[] args) { String value = "cat"; // Step 1: implicitly cast to Object. Object temp = value; // Step 2: cast to String. String value2 = (String) temp; System.out.println(value2); // Step 3: test whether variable is an instance of a class. if (temp instanceof String s) { System.out.println("String s = " + s); } } }cat String s = cat
Numbers can be cast with the same syntax as classes. For casting to a larger byte
size number (a "widening" cast) no cast is required.
byte
size number is reduced to fit in a smaller type, a cast is required.public class Program { public static void main(String[] args) { int size = 5; double size2 = size; // No cast needed. byte size3 = (byte) size; // A larger type must be cast down. System.out.println(size); System.out.println(size2); System.out.println(size3); } }5 5.0 5
ClassCastException
Some casts will fail. And often the compiler will detect an invalid cast at compile-time, saving us the trouble of running an invalid program.
String
, because it is of type StringBuilder
. A ClassCastException
occurs.public class Program { public static void main(String[] args) { StringBuilder builder = new StringBuilder(); builder.append("cat"); Object temp = builder; // This is fine. String value = (String) temp; // This causes an error. System.out.println(value); } }Exception in thread "main" java.lang.ClassCastException: java.lang.StringBuilder cannot be cast to java.lang.String at program.Program.main(Program.java:10)
This concept means an array of a derived class
can be cast to an ancestor class
array. So an array of Strings can be cast to an array of Objects.
public class Program { public static void main(String[] args) { String[] values = { "cat", "dog", "rabbit" }; // A String array is also an Object array. Object[] array = values; // Loop over objects and print String lengths. for (Object v : array) { System.out.println(((String) v).length()); } } }3 3 6
String
A number cannot be cast to a String
—instead we must convert it with a method like Integer.toString
. This method returns a String
version of the int
argument.
public class Program { public static void main(String[] args) { int number = 100; String result = Integer.toString(number); // Number to String. System.out.println(result); } }100
String
to numberWe convert a String
to an integer by parsing it. The Integer.parseInt
method can do this. It receives a String
argument and returns an int
.
public class Program { public static void main(String[] args) { String value = "100"; int result = Integer.parseInt(value); // String to number. System.out.println(result); } }100
int
Suppose we have a long value and wish to have an int
. We can cast the long to an int
directly with a cast expression. This works if the int
can store the long's value.
int
, we will have an incorrect value in the int
.public class Program { public static void main(String[] args) { // Cast long to int directly. long test = 200; int result = (int) test; System.out.println("INT: " + result); } }INT: 200
int
, exactWith Math.toIntExact
, we can safely convert a long to an int
. This may cause an exception if the value cannot be stored in the int
, so we must have a try and catch.
import java.lang.Math; public class Program { public static void main(String[] args) { try { // Use Math.toIntExact to convert long to int. long test = 200; int result = Math.toIntExact(test); System.out.println("INT: " + result); } catch (ArithmeticException ex) { System.out.println("ERROR: " + ex); } } }INT: 200
Double
to int
To truncate a double
, we can cast it to an int
. This eliminates all digits past the decimal place. We can also truncate with Math.floor
and Math.ceil
.
public class Program { public static void main(String[] args) { double value = 100.567; int result = (int) value; // Write results. System.out.println("BEFORE: " + value); System.out.println("AFTER: " + result); } }BEFORE: 100.567 AFTER: 100
Boolean
to int
Sometimes we want to convert a boolean into an int
. Typically we want true to equal 1, and false to be 0. This is done with a simple method and a ternary expression.
We can cast doubles to floats, but we must specify this with a cast expression. Some conversions to float
, like from int
, can be done without any special syntax.
Casting is complex and is often language-specific. Conversions require more steps—they are often reused in many projects and stored in utility classes.