Casting between primitive Java types

Changing a value from one data type to a variable of another type is known as data type conversion.

There are two types of casting,

  1. Primitive Type Casting
  2. Reference Type Casting

Primitive Type Casting

Casting between primitive types enables you to convert the value of one type to another primitive type is called Primitive Type Casting. This is most commonly occurs with the numeric data types . But boolean primitive type can never be used in a cast. Its values must be either true or false and cannot be used in a casting operation.

There are two basic types of Primitive Type Casting widening and narrowing.

Widening conversions (Implicit casting)

A value of narrower(lower size) data type can be converted to a value of a broader (higher size) data type without loss of information is called Widening conversion. This conversion also known as implicit casting .
int i = 1000; double j = i;
In above example, an Automatic Type Casting take place, that is an integer variable (4 Byte) converted into double variable(8 Byte). The casting happened from a lower data type to a higher data type, so there is no data loss .

Widening conversions in Java

From a byte to a short, an int, a long, a float, or a double From a short to an int, a long, a float, or a double From a char to an int, a long, a float, or a double From an int to a long, a float, or a double From a long to a float or a double From a float to a double
NOTE: A widening conversion of an int or a long value to a float value , or of a long value to double value, may result in loss of precision . That is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode.

Narrowing Conversions (Explicit Casting)

Converting from a broader data type (higher size) to a narrower data type (lower size) is called narrowing conversion. This type of conversion can result in loss of information. This is not done implicitly by the JVM and requires explicit casting .
double i = 100.7; int j = (int) i;

In above example a double variable(8 Byte) converted into integer variable (4 Byte) . The casting happened from a higher data type to a lower data type, so can result in loss of information.

Narrowing conversions in Java

From a byte to a char From a short to a byte or a char From a char to a byte or a short From an int to a byte, a short, or a char From a long to a byte, a short, a char, or an int From a float to a byte, a short, a char, an int, or a long From a double to a byte, a short, a char, an int, a long, or a float
An implicit conversion is performed automatically, with no additional input from the developer. An explicit conversion , on the other hand, is not performed automatically and is, instead, dictated by the developer.

Reference Type Casting

Objects of classes also can be cast into objects of other classes when the source and destination classes are related by inheritance and one class is a subclass of the other. The cast can be to its own class type or to one of its subclass or superclass types or interfaces. There are compile-time rules and runtime rules for casting in java. There are two types of Reference Type Casting in Java, they are :
  1. Upcasting
  2. Downcasting

Up-casting is casting to a supertype, while downcasting is casting to a subtype. Supercasting is always allowed, but subcasting involves a type check and can throw a ClassCastException.

Upcasting

Casting a subtype object into a supertype and this is called upcast. In Java, we need not add an explicit cast and you can assign the object directly. Compiler will understand and cast the value to supertype. By doing this, we are lifting an object to a generic level. If we prefer, we can add an explicit cast and no issues.

Downcasting

Casting a supertype to a subtype is called downcast. This is the mostly done cast. By doing this we are telling the compiler that the value stored in the base object is of a super type. Then we are asking the runtime to assign the value. Because of downcast we get access to methods of the subtype on that object. When performing downcasting, that you’re well aware of the type of object you’ll be casting.