我正在编写粘贴到基于Web的系统中运行的Groovy脚本。有一个
可用于在此环境中运行的脚本的类,我将其称为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
。
有没有办法在eval'd字符串中使用BrokenClass
?或者其他一些我没有的方式
考虑解决BrokenClass.reflist
中的错误?一个非常长的switch
块
因为可能的列表名称会改变。
BrokenClass.reflist
的方法签名是:
public static List<Object> reflist(String reflistName, String field);
答案 0 :(得分:1)
我怀疑BrokenClass.reflist()
使用==运算符而不是String.equals()
直接或间接地进行了不正确的字符串比较。有关差异的解释,请参阅this文章。
以下是问题的演示:
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()
被无意中编码为仅使用字符串文字:所有具有相同值的字符串文字引用相同的字符串实例,导致对True的评估。在运行时使用相同的文字值组成的String不引用相同的String实例。
显然BrokenClass.reflist()
应该修复。但您可以使用 interned 字符串解决问题。
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 ==运算符在您需要时工作。