在Groovy中使用ArrayList时,seems that <<
是.add
的别名,但是在这个小例子中它不是:
class MyList extends ArrayList<Integer> {
@Override
boolean add(Integer num) {
println "I'm doing something cool here!"
}
boolean insert(Integer num) {
println "I'm adding it for real"
// super.add(num) works as expected
super << num
}
}
def ml = new MyList();
ml.insert(100)
assert ml.size() == 1
输出:
I'm adding it for real
I'm doing something cool here!
Caught: Assertion failed:
assert ml.size() == 1
| | |
[] 0 false
Assertion failed:
assert ml.size() == 1
| | |
[] 0 false
如果我使用super.add(num)
它会传递断言并且仅打印&#34;我将其添加为真实&#34;
有人可以向我解释为什么super <<
正在调用自己而不是父类,以及为什么在使用<<
时它没有被添加到数组中?
答案 0 :(得分:2)
原因是您已经覆盖了ArrayList.add
方法,但也违反了合同:您不会从重写方法返回任何内容,而应返回boolean
的实例。
super.add(num)
按预期工作,因为您直接致电ArrayList.add
。
<<
的情况下, add
是List
的别名。现在,super << num
将来电委托给DefaultGroovyMethods
,后者又调用了add
上的List
。但在这种特殊情况下,add
中的ArrayList
不是add
中的MyList
而是add
中的class MyList extends ArrayList<Integer> {
@Override
boolean add(Integer num) {
println "I'm doing something cool here!"
return super.add(num)
}
boolean insert(Integer num) {
println "I'm adding it for real"
// super.add(num) works as expected
super << num
}
}
def ml = new MyList();
ml.insert(100)
assert ml.size() == 1
,正如我在开头所写的那样,违反了com.3rdparty.foo
合同。以下代码效果很好:
package com.3rdparty.foo;
public class Bar {
public void someMethod () { ... }
int ppField;
}