我正在编写Groovy脚本,将其粘贴到要运行的基于Web的系统中。有一个可供在此环境中运行的脚本使用的类,我将其称为BrokenClass
。它有一个错误,该错误仅接受字符串文字作为其第一个参数,而不接受其中带有字符串的变量。因此,这将起作用(它返回一个列表):
BrokenClass.reflist('something', 'name')
但是,如果我尝试将变量用作第一个参数,则会出现错误:
list_name = 'something'
BrokenClass.reflist(list_name, 'name')
这将产生消息Metadata RefList[something] cannot be accessed
。
我对BrokenClass没有任何控制权(除了在上面提交错误外)。我试图通过以下方法解决该问题:
list_name = "foo"
list_call = "BrokenClass.reflist(${list_name}, 'name')"
list_values = Eval.me(list_call)
但是,这会产生一个错误:
groovy.lang.MissingPropertyException: No such property: BrokenClass for class: Script1
我尝试import
在字符串中添加,但随后得到unable to resolve class BrokenClass
。
有没有一种方法可以BrokenClass
在评估字符串中使用?还是我没有考虑过解决该bug的其他方法BrokenClass.reflist
?switch
由于可能的列表名称已更改,因此出现了一个很长的块。
方法签名为BrokenClass.reflist
:
public static List<Object> reflist(String reflistName, String field);
我怀疑BrokenClass.reflist()
是通过使用==运算符而不是直接或间接进行了不正确的String比较String.equals()
。请参见本文章的不同的解释。
这是问题的示范:
def a = 'whatever'
def b = 'what' + 'ever'
assert doSomething('whatever') == 'OK'
assert doSomething(a) == 'OK'
assert doSomething(b) == 'ERROR'
def doSomething(String value) {
if(value.is('whatever')) { // In Java this would be: value == "whatever"
'OK'
} else {
'ERROR'
}
}
由于它使用的是引用相等,在Groovy中是由Object.is(Object)
方法完成的,BrokenClass.reflist()
因此无意中将其编码为仅适用于String文字:具有相同值的所有String文字都引用相同的String实例,从而得出True。在运行时以相同的文字值组成的String不会引用相同的String实例。
显然BrokenClass.reflist()
应该是固定的。但是,您可以使用一个Interned String来解决此问题。
def b = 'what' + 'ever'
assert doSomething(b.intern()) == 'OK'
def doSomething(String value) {
if(value.is('whatever')) {
'OK'
} else {
'ERROR'
}
}
如果变量的值与String文字的值匹配,variable.intern()
则将返回与匹配文字相同的String实例。这将使Java ==运算符可以按需工作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句