Groovy def l=[1,2,3]作为阻塞队列

Groovy def l=[1,2,3]作为阻塞队列,groovy,Groovy,如果我将类似于defl=[1,2,3]的东西编写为Socket,这显然是胡说八道,我会得到以下结果: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '[1, 2, 3]' with class 'java.util.ArrayList' to class 'java.net.Socket' 这是有道理的 现在我尝试一些不那么冒险的东西: import java.util.con

如果我将类似于
defl=[1,2,3]的东西编写为Socket
,这显然是胡说八道,我会得到以下结果:

org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '[1, 2, 3]' with class 'java.util.ArrayList' to class 'java.net.Socket' 
这是有道理的

现在我尝试一些不那么冒险的东西:

import java.util.concurrent.BlockingQueue

def l = [1, 2, 3] as BlockingQueue
println l.class
println l
这不会引发异常,并打印以下内容:

class ArrayList1_groovyProxy
[1, 2, 3]
那么什么是
ArrayList1\u groovyProxy
,为什么我能够将列表无误地转换到
BlockingQueue
,尽管它失败了(
l
并不是一个
BlockingQueue
实例)

编辑:


  • 首先,我想指出,
    def l=[1,2,3]as List
    运行良好,并生成
    ArrayList
    的常规实例,尽管
    List
    BlockingQueue
    都是接口
  • 第二,在回答之后,我尝试了以下方法:

    def l = [1, 2, 3] as BlockingQueue
    assert l instanceof BlockingQueue
    println l.class
    println l
    
    这将打印以下行,并且未引发任何断言异常:

    class ArrayList1_groovyProxy
    [1, 2, 3]
    
    但是,此行确实会抛出一个
    MissingMethodException

    l.offer(5)
    
    因此,断言以某种方式成功了,但尝试将
    l
    用作阻塞队列会引发异常

  • 第三,如果我尝试将
    defl=[1,2,3]定义为Map
    此代码:

    def l = [1, 2, 3] as Map
    assert l instanceof Map
    println l
    println l.getClass()
    
    不会产生错误和打印:

    [1, 2, 3]
    class ArrayList1_groovyProxy
    

可爱是一件很棒的事。它可以看到您正在尝试创建一个集合,但它无法理解如何构造BlockingQueue。它正在退回到代理ArrayList。如果您在左侧使用类型声明而不是“def”,它就会爆炸。同样,它变得可爱,因为你正在使用def。很烦人,不是吗?:)

可爱才是最棒的。它可以看到您正在尝试创建一个集合,但它无法理解如何构造BlockingQueue。它正在退回到代理ArrayList。如果您在左侧使用类型声明而不是“def”,它就会爆炸。同样,它变得可爱,因为你正在使用def。很烦人,不是吗?:)

为什么我能够将列表无误地强制转换到BlockingQueue,尽管它失败了(l最终不是BlockingQueue实例)

为什么您如此确定
l
不是
BlockingQueue
实例?以下内容(可以在Groovy控制台中运行)表明它是一个
BlockingQueue
实例:

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
仅供参考,通过定义变量的类型,而不是使用
def
,可以消除关于类型的许多不确定性

为什么我能够将列表无误地强制转换到BlockingQueue,尽管它失败了(l最终不是BlockingQueue实例)

为什么您如此确定
l
不是
BlockingQueue
实例?以下内容(可以在Groovy控制台中运行)表明它是一个
BlockingQueue
实例:

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

仅供参考,您可以通过定义变量的类型来消除关于类型的许多不确定性,而不是使用
def

使用
x,因为y
而不是强制,这是强制(请参阅)

强制不会在强制转换时检查类型安全性

另外,
BlockingQueue
是一个接口。我不知道为什么要将对象强制转换为接口

尝试运行以下命令:

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())
​
你会得到:

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]

你不能有一个接口的实例,所以它不知道你要求它做什么。例如,尝试运行
newblockingqueue()
,您不能这样做,因为您不能拥有接口的实例。这就是为什么不能将对象强制转换为接口

使用
x作为y
而不是施法,这是强制(参见)

强制不会在强制转换时检查类型安全性

另外,
BlockingQueue
是一个接口。我不知道为什么要将对象强制转换为接口

尝试运行以下命令:

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())
​
你会得到:

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]

你不能有一个接口的实例,所以它不知道你要求它做什么。例如,尝试运行
newblockingqueue()
,您不能这样做,因为您不能拥有接口的实例。这就是为什么不能将对象强制转换为接口

这种“可爱”有多普遍?悄悄失败的施法可能会导致令人讨厌的、难以发现的虫子。这种“可爱”有多普遍?悄悄失败的强制转换可能会导致令人讨厌的、难以发现的错误。使用
@TypeChecked
@CompileStatic
l
并不是阻塞队列,因为a)类名是
ArrayList1\u groovyProxy
B)
l.offer(5)
抛出一个
Groovy.lang.MissingMethodException:
。断言没有失败的事实只会让这种行为变得更奇怪。另外,我很欣赏静态输入技巧。它肯定是一个
阻塞队列
,如果类型为
BlockingQueue
的变量没有被阻塞,那么断言和对该变量的赋值将失败。使用
@TypeChecked
@CompileStatic
l
更是如此,因为a)类名是
ArrayList1\u groovyProxy
B)
l.offer(5)
抛出一个
Groovy.lang.MissingMethodException:
。断言没有失败的事实只会让这种行为变得更奇怪。另外,我也很欣赏静态键入技巧。它肯定是一个
BlockingQueue
,如果不是,断言和对
BlockingQueue
类型变量的赋值将失败。
def l=[1,2,3]as List
工作正常,尽管
List
也是一个接口。我得到
类java.util.ArrayList
[1,2,3]
@Malt I。。。我不知道你说的“工作很好”是什么意思。这仍然无效,无法实例化接口,请尝试
new List()
new BlockingQueue()
。您不能,因为接口正在定义契约。你不能在一个预先存在的实体上履行一个新的合同,这个实体最初不受合同的约束