-1

Consider the following snippet:

class MyClass<E>{
...
public void checkType(Object o){
 if(o instanceof List<E>){ //this gives compilation error
   List<E> list = (List<E>)o; //this gives unchecked warning
 }
}
...
}
  • Here, the instanceof will give a compilation error as the type of E is not known at run-time.
  • Why does the (List<E>)o give a warning? I think this should be reported as an error by the compiler on the same grounds.

I'm not sure if there can be any case why this will not be an error and only qualify as warning.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
theutonium.18
  • 483
  • 2
  • 7
  • 3
    A cast operation never results in a compilation error. A cast will just alter the compiler's "view". Basically, if we as developers cast, we take responsibility for the cast. – Turing85 Nov 05 '21 at 18:55
  • @Turing85 : but then why is compiler allowing a syntax that does not stand to its meaning? - it is clearly known that under all circumstances AFAIK this will never ever be true. Had it been the cast to a reified type - this still might have been a possibility - but with a **Variable type parameter** - there is no chance I guess. – theutonium.18 Nov 05 '21 at 18:58
  • 1
    @Turing85 That's not true. Casting from `String` to `Integer` is a compilation error. I think a better answer is that if unchecked casts become errors too, then many things become impossible to do. – Sweeper Nov 05 '21 at 18:59
  • @Sweeper true. We can only "downcast" along the hierarchy, not "sidecast". – Turing85 Nov 05 '21 at 19:00
  • 1
    @theutonium.18 "*but then why is compiler allowing a syntax that does not stand to its meaning?*" - The meaning is defined by the [JLS](https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.5). – Turing85 Nov 05 '21 at 19:02
  • @theutonium.18 Also note, the cast from `Object` to `List` is only partially unchecked. The runtime can still check whether `o` is a `List`. It just can't check whether it is a list of _**E**_s. – Sweeper Nov 05 '21 at 19:05
  • @Sweeper : then in that case - the compiler can make only `List>` as valid candidate for this operation - as it does in the case of `instanceOf` checks?. – theutonium.18 Nov 05 '21 at 19:34
  • @theutonium.18 As I said in my first comment, it _could_ be designed to disallow any unchecked cast, but then the type system would be too strict, making many things impossible to do. For example, you wouldn't be able to create a `E[]`, where `E` is a type variable. – Sweeper Nov 05 '21 at 19:38
  • @Sweeper : agree on this part - but if u consider the case of arrays - the type system allows `new ArrayList>[4]` for example - but not `new ArrayList[4]` - Why can't same be done for cast operations? – theutonium.18 Nov 05 '21 at 19:41
  • Another reason may be *backward compatibility* (according to [this article](https://www.baeldung.com/java-warning-unchecked-cast)). – MC Emperor Nov 05 '21 at 20:43

1 Answers1

0

Just came across this piece of code that suggests why Non-Reified Casts with Type Parameters can be a warning only and not an error:

public static <T> List<T> getAsList(Collection<T> c){
        if(c instanceof List<?>){
            return (List<T>)c;
        }
        ...
    }
theutonium.18
  • 483
  • 2
  • 7