Description of the Rule
Narrowing reference conversions should always check for type-compatibility.
According to the spec “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.”.
And consequently the compiler cannot warn about these cases.
In our particular example (see the link in the references below) we had an object holding a raw reference to a generic class Link<T>
. A method of that referenced object gets called, returning an instance of the generic type parameter, hence Object
at runtime. This object was down casted to something it was not compatible causing a ClassCastException at runtime. While this is the expected behaviour, it would have been good to have it flagged earlier.
Noncompliant Code
public class Test {
public Object returnAnObject() {
return new Object();
}
public Number returnAnObjectAsNumber() {
return (Number) returnAnObject();
}
}
Compilant Code
public class Test {
public Object returnAnObject() {
return new Object();
}
public Number returnAnObjectAsNumber() {
Object anObject = returnAnObject();
return anObject instanceof Number ? anObject : null;
}
}
Exceptions
Maybe, if the method is declared to throw a ClassCastException that should not raise an issue, hence the following would be compliant as well
public class Test {
public Object returnAnObject() {
return new Object();
}
public Number returnAnObjectAsNumber() throws ClassCastException {
Object anObject = returnAnObject();
return (Number) anObject;
}
}
External references and/or language specifications
- Chapter 5. Conversions and Contexts
- [Teaser] TeaserImpl tries to cast Asset to Page (#2343) · adobe/aem-core-wcm-components@1af8f68 · GitHub
type
Bug