Groovy def l = [1, 2, 3] as BlockingQueue

前端 未结 3 1468
眼角桃花
眼角桃花 2021-01-28 01:46

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         


        
相关标签:
3条回答
  • 2021-01-28 02:03

    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.

    0 讨论(0)
  • 2021-01-28 02:17

    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? :)

    0 讨论(0)
  • 2021-01-28 02:22

    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.

    0 讨论(0)
提交回复
热议问题