The knowledge sharing zone - Guruzon.com

What is type casting in java

This tutorial contains the details about Type Casting or Reference Variable Casting in Java. It also different examples of type casting and limitations of it.
reviews

What is type casting in java

  • Type casting is basically an assignment of a value of one type to a variable of another type.
  • Basically there are two type of casting:
    • Upcasting or Automatic type conversions
    • Downcasting or Explicit type conversions

Upcasting - Automatic type conversions

  • If the two types are compatible then Java will perform the conversion automatically.
  • When you are casting up the reference variable to the inheritance tree to a more general class it is called a upcast or upcasting of variable.

Example of Upcasting or Automatic type conversions

It is always possible to assign an int value to a long variable, For example,

byte b = 10;
int i = b;
long l = i;

Upcasting works fine without any explicit cast.

class Animal { }
class Dog extends Animal { }
class DogTest {
      public static void main(String [] args) {
      Dog d = new Dog();

      // All Dogs are Animal hence upcasting is fine.
      Animal a1 = d; // upcast ok with no explicit cast
      Animal a2 = (Animal) d; // upcast ok with an explicit cast
   }
}

Automatic type conversion will occur only if the following two conditions are met:

  • The two types are compatible.
  • The destination type is larger than the source type.

When these two conditions are met, a widening conversion takes place. For example, the int type is always large enough to hold all valid byte values, so no explicit cast statement is required.

  • For widening conversions, the numeric types, including integer and floating-point types, are compatible with each other.
  • However, there are no automatic conversions from the numeric types to char or boolean, And also char and boolean are not compatible with each other.
  • As mentioned earlier, Java also performs an automatic type conversion when storing a literal integer constant into variables of type byte, short, long, or char.

Downcasting or Explicit type conversions

  • When you are casting down the reference variable to the inheritance tree to a more specific class it is called a downcast or downcasting of variable.
  • Remember that, Not all types are compatible hence not all type conversions are implicitly allowed.
  • For example, there is no automatic conversion defined from double to byte, But it is still possible to obtain a conversion between incompatible types.

Example of downcasting or Explicit type conversions

To perform conversion between incompatible types, you must need to use variable casting, which performs an explicit conversion between incompatible types.

class Animal { }
class Dog extends Animal { }
class DogTest {
      public static void main(String [] args) {
      
      Animal a = new Animal();
      Dog d = new Dog();
      
      // Every animal can't be Dog so be careful with downcasting
      // other wise it may throw ClassCastException at runtime.

      Dog d1 = a; // won't compile, as downcast needs explicit casting

      Animal a1 = d; // upcast ok with no explicit cast
      Dog d2 = (Dog) a1; // downcast needs explicit casting, works fine.

      // Animal can't EVER be a String
      String s = (String) animal; // this line won't compile
   }
}


Casting incompatible types in java

  • Although the automatic type conversions are helpful, they will not fulfill all needs. For example, what if you want to assign an int value to a byte variable? This conversion will not be performed automatically, because a byte is smaller than an int.
  • This kind of conversion is sometimes called a narrowing conversion, since you are explicitly making the value narrower so that it will fit into the target type.
  • To create a conversion between two incompatible types, you must use a cast. A cast is simply an explicit type conversion. It has this general form: (target-type) value
  • Here, target-type specifies the desired type to convert the specified value to. For example, the following fragment casts an int to a byte.
  • If the integer’s value is larger than the range of a byte, it will be reduced modulo (the remainder of an integer division by the) byte’s range.

int a;
byte b;
// ...
b = (byte) a;

  • A different type of conversion will occur when a floating-point value is assigned to an integer type: truncation. As you know, integers do not have fractional components.
  • Thus, when a floating-point value is assigned to an integer type, the fractional component is lost.
  • For example, if the value 1.23 is assigned to an integer, the resulting value will simply be 1. The 0.23 will have been truncated. Of course, if the size of the whole number component is too large to fit into the target integer type, then that value will be reduced modulo the target type’s range.
  • The following program demonstrates some type conversions that require casts:
// Demonstrate casts.
class Conversion {
   public static void main(String args[]) {
      byte b;
      int i = 257;
      double d = 323.142;
      System.out.println("\nConversion of int to byte.");
      b = (byte) i;
      System.out.println("i and b " + i + " " + b);
      System.out.println("\nConversion of double to int.");
      i = (int) d;
      System.out.println("d and i " + d + " " + i);
      System.out.println("\nConversion of double to byte.");
      b = (byte) d;
      System.out.println("d and b " + d + " " + b);
   }
}
Output:
   Conversion of int to byte.
   i and b 257 1
   Conversion of double to int.
   d and i 323.142 323
   Conversion of double to byte.
   d and b 323.142 67

Automatioc type casting / promotion in expression

  • There is one more place where certain type conversions may occur: In expressions.
  • In an expression, the precision required of an intermediate value will sometimes exceed the range of either operand.
  • For example, examine the following expression:
byte a = 40;
byte b = 50;
byte c = 100;
int d = a * b / c; // a * b exceeds the range of byte
  • The result of the intermediate term a * b easily exceeds the range of either of its byte operands.
  • To handle this kind of problem, Java automatically promotes each byte, short, or char operand to int when evaluating an expression.
  • This means that the subexpression a * b is performed using integers-not bytes.
  • Thus, 2,000, the result of the intermediate expression, 50 * 40, is legal even though a and b are both specified as type byte.
  • As useful as the automatic promotions are, they can cause confusing compile-time errors.
  • For example, this seemingly correct code causes a problem:

byte b = 50;
b = b * 2; // Compile time error, Cannot assign an int to a byte!

  • The code is attempting to store 50 * 2, a perfectly valid byte value, back into a byte variable.
  • However, because the operands were automatically promoted to int when the expression was evaluated, the result has also been promoted to int. Thus, the result of the expression is now of type int, which cannot be assigned to a byte without the use of a cast.
  • This is true even if, as in this particular case, the value being assigned would still fit in the target type.
  • In cases where you understand the consequences of overflow, you should use an explicit cast, such as
byte b = 50;
b = (byte)(b * 2); // which yields the correct value of 100.

Root cause of ClassCastException in java

  • Below code compiles, But When we try to run it, we'll get an exception something like this: java.lang.ClassCastException
class Animal { }
class Dog extends Animal { }
class DogTest {
   public static void main(String [] args) {
      Animal animal = new Animal();
      Dog d = (Dog) animal; // compiles but fails later
   }
}
  • Here, all the compiler can do is verify that the two types are in the same inheritance tree, so that depending on whatever code might have come before the downcast, it's possible that animal is of type Dog. The compiler must allow things that might possibly work at runtime.
  • However, if the compiler knows with certainty that the cast could not possibly work, compilation will fail. The following replacement code block will not compile:

Animal animal = new Animal();
Dog d = (Dog) animal;
String s = (String) animal; // animal can not ever be a String

Keypoints about reference variable type casting

  • Type casting is basically an assignment of a value of one type to a variable of another type.
  • Type casting are of two type: Upcasting & Downcasting.
  • Upcasting is always automatic, You don't need to specify target type.
  • Upcasting is basically assigning an object to more broader or wider type variable, It's like - All dogs are animal, Any object in java is of type java.lang.Object etc..
  • Downcasting is always explicit, You have to specify target type.
  • Downcasting is basically assigning an object to more narrower or smaller type variable, It's like - Some animals are dog, Some object in java is of type java.lang.Object etc..
  • If the compiler knows with certainty that the cast is not possible, Code compilation will fail.
  • If the compiler knows with certainty that the cast is not possible, Code compilation will fail.
  • If compiler finds broader object reference assignment to narrower object type during runtime, It will throw ClassCastException. For example,
      Animal animal = new Animal();
      Dog d = (Dog) animal; // compiles but fails later
  • When using downcasting, It always preferrable to use instanceof operator before doing the actual downcasting, For example,
      Animal animal = new Animal();
      if(animal instanceof Dog) {
          Dog d = (Dog) animal;
      }

FAQ about reference variable type casting


What is reference variable type casting in java?


What are the types of type casting in java?


When automatic type casting will occur in java?


What can be root cause or problem when ClassCastException is thrown by JVM in your program?


When explicit type casting required?


Can we cast incompatible types in java?


What is use of type casting in java?


What is downcasting / downcast in java?


What is upcasting / upcast in java?


 

You would also like to read:

Default values for primitives and reference types
Instance initialization and static block in java
Pass by value and pass by reference in java
Stack and heap memory variables
Different variable scopes in java

Comments :

Name :
Email :
Comment :
Verify Text :
capch image, refresh page if not loaded somehow