Let me add to the previous answers for completeness. There are 2 levels to your question.
The "unchecked cast" warning is not about the types that you are trying to cast to/from. It's about the fact that there is no difference at runtime between Channel<X>
and Channel<Y>
due to type erasure. So a cast from one to the other will never fail at runtime even if it's wrong: it is not checked at runtime (hence the "unchecked"). This may lead to subtle bugs because you're polluting the heap.
This is different when casting non-generic types, like Any
to String
, or the raw part of generic types, like List<*>
to MutableList<*>
. Those would properly fail at runtime if the instance in question is not of the correct type.
Shouldn't this cast always be safe since Channel<out Message>
can only contain objects of type Message or subclasses of type Message
?
Actually no, it's not safe, as other answers have shown. The out
in the declaration prevents you from sending elements into this channel (it's out
-only, you can't put things in
). This prevents you from inserting things that the channel cannot support. Casting would make the compiler allow that, which would be incorrect at runtime.