If I write something like def l = [1, 2, 3] as Socket
which is obviously nonsense, I get this:
org.codehaus.groovy.runtime.typehandling.GroovyCastE
Using x as y
is not casting, it's Coercion (see Section 8.7 of the Groovy Manual).
Coercion does not check type safety when casting.
Also, BlockingQueue
is an interface. I'm not sure why you would cast an object as an interface.
Try running this:
import java.util.concurrent.LinkedBlockingQueue
LinkedBlockingQueue l = [1, 2, 3] as LinkedBlockingQueue
println(l instanceof LinkedBlockingQueue)
println(l.class)
println(l.metaClass.methods*.name.sort().unique())
You get:
true
class java.util.concurrent.LinkedBlockingQueue
[add, addAll, clear, contains, containsAll, drainTo, element, equals, getClass, hashCode, isEmpty, iterator, notify, notifyAll, offer, peek, poll, put, remainingCapacity, remove, removeAll, retainAll, size, take, toArray, toString, wait]
You can't have an instance of an interface, so it had no idea what you asked it to do. For instance, try running new BlockingQueue()
, you can't because you can't have an instance of an interface. This is why you cannot cast an Object to be an interface.
It's just Groovy being cute. It's able to see that you're trying to create a collection, but it can't figure out how to construct a BlockingQueue. It's falling back to a proxied ArrayList. If you'd gone with a type declaration on the left side instead of a "def," it would have blown up. Again, it's getting cute because you're using a def. Annoying, isn't it? :)
why am I able to cast the list to BlockingQueue without error despite the fact that it fails (l doesn't end up being an BlockingQueue instance)?
Why are you so sure that l
is not a BlockingQueue
instance? The following (which you can run in the Groovy console) indicates that it is a BlockingQueue
instance:
import java.util.concurrent.BlockingQueue
// this assignment would be impossible if l is not a BlockingQueue
BlockingQueue l = [1, 2, 3] as BlockingQueue
// this assertion would throw an exception if l is not a BlockingQueue
assert l instanceof BlockingQueue
FYI, you can remove a lot of uncertainty about types by defining the types of your variables, rather than using def
.