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
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()
。您不能,因为接口正在定义契约。你不能在一个预先存在的实体上履行一个新的合同,这个实体最初不受合同的约束