Reputation: 5759
taken from http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html
5.1.6. Narrowing Reference Conversion Six kinds of conversions are called the narrowing reference conversions: From any reference type S to any reference type T, provided that S is a proper supertype of T ...
public class S {}
public class T extends S {}
As the following throws a java.lang.ClassCastException
S s = new S();
T t = (T)s;
does the 'conversion' simply refer to the following that compiles does not throw a run-time exception.
S s = null;
T t = (T)s;
What are the reasons for performing this conversion?
Upvotes: 4
Views: 869
Reputation: 2177
Although implicit in Sotirios Delimanolis's example (// something
), I wanted to add to this and make it explicit that if you have:
public class S {}
public class T extends S {}
then the narrowing conversion in the JLS not only refers to your example with null
but rather to:
S s = new T();
T t = (T) s; // compiles and won't give a ClassCastException
while as you mentioned
S s = new S();
T t = (T) s;
will compile but will throw a ClassCastException
Upvotes: 2
Reputation: 279930
Further in the document you quoted, it states
Such conversions require a test at run time to find out whether the actual reference value is a legitimate value of the new type. If not, then a
ClassCastException
is thrown.
The conversion applies to your first example as well. A value of type S
is not a legitimate value of type T
. The value null
is a legitimate value of type T
.
The null reference can always be assigned or cast to any reference type (§5.2, §5.3, §5.5).
The compiler trusts that you know what you are doing. The JVM does not.
A narrowing reference conversion is more commonly known as a downcast. It's typically used in situations where you have references of some supertype but would like to do something more specific with them depending on their actual type.
Object superTypeReference = // something;
if (superTypeReference instanceof List) {
List<?> subtypeReference = (List<?>) superTypeReference;
subtypeReference.clear();
}
Upvotes: 3