Java Cast and Conversions

Java Cast and Conversions

In this Java fundamentals tutorial let us see about casting in Java. 

This tutorial is having two parts, the first one is for casting on reference types and the second is for primitives cast. 

In each part let us see about the different types of cast available and how we can use them in Java.

First we have to fix the terminologies. Java language specification (SE7-JLS-5.0) uses the word ‘conversion’ as a superset for anything and everything related to transforming objects. 

The word ‘cast’ is used at places where the developer needs to explicitly tell the compiler that the instance value needs to be converted. 

Attaching the cast-operator (a type between parentheses), before an object is referred as cast.

type-safety in Java

Type-safety is the mechanism provided in a programming language to ensure that there are no issues because of type mismatch between a variable and value attempted to store in it. 

In Java to ensure type-safety, during compile time the compiler will check for type information between variables using the static type information available. 

Then during runtime the values are checked for compatibility before storing in a variable.

Java Cast and Conversions_第1张图片

As per Java language specification (SE7-JLS-5.0) conversions are broadly categorized as,

  • Identity conversions
  • Widening primitive conversions
  • Narrowing primitive conversions
  • Widening reference conversions
  • Narrowing reference conversions
  • Boxing conversions
  • Unboxing conversions
  • Unchecked conversions
  • Capture conversions
  • String conversions
  • Value set conversions

Identity Conversion

This is given for theoretical completeness. Assigning two instance of same type is identity conversion.

	Integer i1;
	Integer i2 = new Integer(2);

	i1 = i2; //identity conversion
	// cast not required, but done compiler will not complain
	i1 = (Integer) i2;

Primitive Conversions and Cast in Java

These are the conversions between the primitives.

Widening Primitive Conversion

“A widening primitive conversion does not lose information about the overall magnitude of a numeric value.” 

There is no cast required and will never result in a runtime exception. Following are the possible widening conversions,

  • byte to short, int, long, float, or double
  • short to int, long, float, or double
  • char to int, long, float, or double
  • int to long, float, or double
  • long to float or double
  • float to double
class WideningConversion {
    public static void main(String[] args) {
	int i = 123456789;
	float f = i;
    }
}

Narrowing Primitive Conversion

“A narrowing primitive conversion may lose information about the overall magnitude of a numeric value and may also lose precision and range.” Cast required between types. Overflow and underflow may happen but a runtime exception will never happen. 

Following are the possible narrowing conversions,

  • short to byte or char
  • char to byte or short
  • int to byte, short, or char
  • long to byte, short, char, or int
  • float to byte, short, char, int, or long
  • double to byte, short, char, int, long, or float
package com.javapapers.java;

public class NarrowingPrimitiveConversion {
	public static void main(String[] args) {

	float f = Float.POSITIVE_INFINITY;
	long l = (long) f;
	int i = (int) f;

	System.out.println("long: " + l + " int: " + i);

	int j = 255;
	byte b = (byte) j;

	// size is too large and resulted in negative
	System.out.println(b);
  }
}

Reference Conversions and Cast in Java

In this section let us see about categories, widening reference conversion and narrowing reference conversion. 

With respect to classes and objects, there are four categories to understand for casting.

public class JavaCast {
    public static void main(String... args) {
        
        Integer integer = new Integer(10);
        Float floatt = new Float(20F);

        //this is not a cast - error
        // integer = floatt; //compiler error - incompatible types
        // integer = (Integer) floatt;//compiler error - inconvertible types
        
        //upcast - widening conversion
        Object obj = integer; //no explicit cast required
        System.out.println(obj);

        //downcast - narrowing conversion
        Integer in = (Integer)obj;//only subtype
        System.out.println(in);

        //downcast - Object to String
        //runtime issue - instance Object is not of String
        String str = (String)obj;//ClassCastException
    }
}
  1. Assigning a Float object to Integer directly has got nothing to do with casting and it will throw a compile error as incompatible type. Casting a Float into Integer is not proper and will get compile error as inconvertible types. Casting in Java is done within same hierarchy of types, that is between inherited types.
  2. upcast – 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.
  3. downcast – 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.
  4. ClassCastExcpetion – We get ClassCastException in a downcast. In principle, we guarantee the compiler that the instance value of is subtype and ask it to cast. But during runtime, because of unforeseen circumstances, the value is not of expected subtype. In such cases, we get ClassCastException.

Boxing and Unboxing Conversions

Converting from a primitive type to its corresponding reference type is boxing conversion and vice versa is unboxing conversion.

Examples are,

  • From primitive boolean to type Boolean
  • From primitive int to type Integer
	int i = 10;
	Integer iObj = new Integer(100);

	iObj = i;//boxing conversion
	i = iObj;//unboxing conversion

String Conversion

String conversion applies only to the ‘+’ operator, when one operand is a String and another is a primitive type. 

In such a case, primitive type is converted to its corresponding reference type and then it is converted using the toString() method. 

No cast is required.

	int i = 10;
	String str1 = "";

	String str2 = str1 + i; //string conversion

Unchecked and Capture Conversion will be discussed in the next tutorial as part of the generics series.

你可能感兴趣的:(Java Cast and Conversions)