Casting Suppose we have a collection of classes that are related to each other in the following way. A / \ B C / \ D E | F Let T1 and T2 be type variables that represent classes from the above hierarchy. T1 and T2 might be related to each other in three ways. 1) We may have T1 as a subclass of T2, like this. T2 / \ B C / \ D T1 | F 2) We may have T2 as a subclass of T1, like this. T1 / \ B C / \ D T2 | F 3) We may have neither as a subclass of the other, like this. A / \ T1 C / \ D T2 | F Now consider the following line of code that makes a reference variable of one type refer to an object of a different type. . T2 x = new T1(); Here is what you need to remember. i) This code will compile in case (1) above. ii) This code will fail to compile in cases (2) and (3) above. In general, Java has the following rule (stated four equivalent ways): "The type of an object must always be a subclass of the type of any reference variable that refers to it." "An object must always be lower in the inheritance tree than any reference variable that refers to it." "The type of a reference variable must always be a superclass of the type of any object it refers to." "A reference variable must always be higher in the inheritance tree than any object it refers to." We will use this rule to help us understand casting. Now consider the following lines of code that contain a cast. T1 x; // assign an object to x T2 y = (T2)x; Here is what you need to remember. i) This code will compile in cases (1) and (2) above. ii) This code will fail to compile in case (3) above. iii) This code will run successfully in case (1) above (this is a "widening" cast). iv) This code MAY throw a runtime cast exception in case (2) because case (2) MAY violate the rule stated above (this is a "narrowing" cast). Here is an example of case (2) that causes a runtime cast exception. T1 x; x = new C(); T2 y = (T2)x; // fails at runtime (why?) At runtime, the third line tries to make a E reference variable refer to a C object, but that would make the reference variable lower in the tree than the object it refers to. Here is a way to summarize casting of reference variables. For the code T1 x; // assign an object to x T2 y = (T2)x; which casts from T1 to T2, if T1 subclass of T2, this is widening, may be implicit, always error free if T2 subclass of T1, this is narrowing, must be explicit, may throw exception or, to put it another way, if T2 is higher than T1, this is widening, may be implicit, always error free if T1 is higher than T2, this is narrowing, must be explicit, may throw exception