# Casting in Java

# Casting for primitives

In Java, for primitives we have 2 kinds of casting: widening/upcasting & narrowing/down casting.

Widening casting (Upcasting) (could be done automatically)

double <- float <- long <- int <- short <- byte

Widening casting
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Demo1Application {

	public static void main(String[] args) throws InterruptedException {
		SpringApplication.run(Demo1Application.class, args);

		int myInt = 7;

		// Automatic casting: int -> double (no loose of data)
		double myDouble = myInt;

		System.out.println(myInt);
		System.out.println(myDouble);
	}
}

And when we run we receive:

7
7.0

Narrowing casting (Downcasting) (must be done manually)

double -> float -> long -> int -> short -> byte

Narrowing casting
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Demo1Application {

	public static void main(String[] args) throws InterruptedException {
		SpringApplication.run(Demo1Application.class, args);

		double myDouble = 7.8;
		int myInt;

		// Manual casting: double -> int (loose of data could exist)
		myInt  = (int)myDouble;

		System.out.println(myInt);
		System.out.println(myDouble);
	}
}

And when we run we receive:

7
7.8

# Casting for reference type variables

The main idea of the casting is the same. Please take a look at the following examples.

Casting examples
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Demo1Application {

	public static void main(String[] args) throws InterruptedException {
		SpringApplication.run(Demo1Application.class, args);

		Vehicle vehicle = new Vehicle("VE 100");
		Car car = new Car("CA 100");

		System.out.println("Widening casting (Upcasting)");
		System.out.println("----------------------------");

		Vehicle vehicle2 = car;
		vehicle2.changePlateNumber("AAA");

		System.out.println(" ");
		System.out.println("Narrowing casting (Downcasting)");
		System.out.println("----------------------------");

		Car car2 = (Car) vehicle2;
		car2.changePlateNumber("AAA");
		car2.changeColor("Blue");
	}
}

When we run the code above we will see in the console:

Widening casting (Upcasting)
----------------------------
Car :> Plate number changed.
 
Narrowing casting (Downcasting)
----------------------------
Car :> Plate number changed.
Car :> Change color.

Here we have a Boxing/ unboxing example:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Demo1Application {

  public static void main(String[] args) throws InterruptedException {
    SpringApplication.run(Demo1Application.class, args);

    int x = 10;

    //Boxing
    Integer x1 = x;
    Integer x2 = x1;
    x1 = x1 * 10;

    //Unboxing
    int int1 = x1;

    x = 8;

    System.out.println("x="+x);
    System.out.println("x1="+x1);
    System.out.println("x2="+x2);
    System.out.println("int1="+int1);
  }
}

... and the result is :

x=8
x1=100
x2=10
int1=100