CHAPTER 5: Conversions and Promotions Previous
Previous
Java Language
Java Language
Index
Index
Next
Next

5.5 Casting Conversion

Casting conversion is applied to the operand of a cast operator (S15.15): the type of the operand expression must be converted to the type explicitly named by the cast operator. Casting contexts allow the use of an identity conversion (S5.1.1), a widening primitive conversion (S5.1.2), a narrowing primitive conversion (S5.1.3), a widening reference conversion (S5.1.4), or a narrowing reference conversion (S5.1.5). Thus casting conversions are more inclusive than assignment or method invocation conversions: a cast can do any permitted conversion other than a string conversion.

Some casts can be proven incorrect at compile time; such casts result in a compile-time error.

A value of a primitive type can be cast to another primitive type by identity conversion, if the types are the same, or by a widening primitive conversion or a narrowing primitive conversion.

A value of a primitive type cannot be cast to a reference type by casting conversion, nor can a value of a reference type be cast to a primitive type.

The remaining cases involve conversion between reference types. The detailed rules for compile-time correctness checking of a casting conversion of a value of compile-time reference type S (source) to a compile-time reference type T (target) are as follows:

See Chapter 8 for the detailed specifications of classes, Chapter 9 for interfaces, and Chapter 10 for arrays.

If a cast to a reference type is not a compile-time error, there are two cases:

If a run-time exception is thrown, it is a ClassCastException (S11.5.1.1, S20.22).

Here are some examples of casting conversions of reference types, similar to the example in S5.2:


public class Point { int x, y; }

public interface Colorable { void setColor(int color); }


public class ColoredPoint extends Point implements Colorable 
{
	int color;
	public void setColor(int color) { this.color = color; }
}


final class EndPoint extends Point { }


class Test {

	public static void main(String[] args) {
		Point p = new Point();
		ColoredPoint cp = new ColoredPoint();
		Colorable c;


		// The following may cause errors at run time because
		// we cannot be sure they will succeed; this possibility
		// is suggested by the casts:
		cp = (ColoredPoint)p;							// p might not reference an
									// object which is a ColoredPoint
									// or a subclass of ColoredPoint
		c = (Colorable)p;							// p might not be Colorable


		// The following are incorrect at compile time because
		// they can never succeed as explained in the text:
		Long l = (Long)p;							// compile-time error #1
		EndPoint e = new EndPoint();
		c = (Colorable)e;							// compile-time error #2

	}

}

Here the first compile-time error occurs because the class types Long and Point are unrelated (that is, they are not the same, and neither is a subclass of the other), so a cast between them will always fail.

The second compile-time error occurs because a variable of type EndPoint can never reference a value that implements the interface Colorable . This is because EndPoint is a final type, and a variable of a final type always holds a value of the same run-time type as its compile-time type. Therefore, the run-time type of variable e must be exactly the type EndPoint , and type EndPoint does not implement Colorable .

Here is an example involving arrays (Chapter 10):


class Point {

	int x, y;

	Point(int x, int y) { this.x = x; this.y = y; }

	public String toString() { return "("+x+","+y+")"; }

}

public interface Colorable { void setColor(int color); }


public class ColoredPoint extends Point implements Colorable 
{

	int color;

	ColoredPoint(int x, int y, int color) {
		super(x, y); setColor(color);
	}


	public void setColor(int color) { this.color = color; }

	public String toString() {
		return super.toString() + "@" + color;
	}

}


class Test {

	public static void main(String[] args) {
		Point[] pa = new ColoredPoint[4];
		pa[0] = new ColoredPoint(2, 2, 12);
		pa[1] = new ColoredPoint(4, 5, 24);
		ColoredPoint[] cpa = (ColoredPoint[])pa;
		System.out.print("cpa: {");
		for (int i = 0; i < cpa.length; i++)
			System.out.print((i == 0 ? " " : ", ") + cpa[i]);
		System.out.println(" }");
	}

}

This example compiles without errors and produces the output:

cpa: { (2,2)@12, (4,5)@24, null, null }

The following example uses casts to compile, but it throws exceptions at run time, because the types are incompatible:


public class Point { int x, y; }

public interface Colorable { void setColor(int color); }


public class ColoredPoint extends Point implements Colorable 
{

	int color;


	public void setColor(int color) { this.color = color; }

}


class Test {

	public static void main(String[] args) {

		Point[] pa = new Point[100];


		// The following line will throw a ClassCastException:
		ColoredPoint[] cpa = (ColoredPoint[])pa;


		System.out.println(cpa[0]);


		int[] shortvec = new int[2];


		Object o = shortvec;


		// The following line will throw a ClassCastException:
		Colorable c = (Colorable)o;


		c.setColor(0);

	}

}



Top© 1996 Sun Microsystems, Inc. All rights reserved.