模棱两可的方法调用。 Patchingchain 中的 add(Unit) 和 AbstractCollection 中的 add(Unit) 都匹配”

Ambiguous method call. Both add(Unit) in Patchingchain and add(Unit) in AbstractCollection match"

嗨,我 运行 intellij idea 中包含这些说明的代码

SootClass c = Scene.v().loadClassAndSupport(name);
final Body b = Jimple.v().newBody(m);
PatchingChain<Unit> units = b.getUnits();       
LocalGenerator locGen = new LocalGenerator(b)
Local locThis = locGen.generateLocal(RefType.v(c));
units.add(Jimple.v().newIdentityStmt(locThis, Jimple.v().newThisRef(RefType.v(c))));

我在最后一行收到此内容的错误

"Ambiguous method call. Both add(Unit) in Patchingchain and add(Unit) in AbstractCollection match"

如何解决这个错误?

解决办法就是在最后一行将units转为PatchingChain

((PatchingChain) units).add(Jimple.v().newIdentityStmt(locThis, Jimple.v().newThisRef(RefType.v(c))))

有什么问题吗?

我查看了 Soot 源代码。 PatchingChain 扩展了 AbstractCollection 并且它的 header 看起来像这样:

public class PatchingChain<E extends Unit> extends AbstractCollection<E> implements Chain<E>

E extends Unit 部分很重要。当您查看 java.util.AbstractCollection 代码时,它如下所示:

public abstract class AbstractCollection<E> implements Collection<E>

所以我们有带类型参数部分 E 的基础 class 和带部分 [=17 的派生 class =].

AbstractCollection 的方法 add(E e)PatchingChain 的方法 add(E o) 似乎具有相同的签名,因此看起来像来自 PatchingChain(派生的 class)应该覆盖来自 AbstractCollection(基础 class)的那个,并且编译器应该知道使用派生的。 但是,事实上,add 方法并没有被重写,而是被重载。这些泛型 classes 中参数类型的声明会影响编译器如何看待这些方法。这两个 add 方法作为 add(E)add(E extends Unit) 对编译器可见,因此它们具有不同的签名,并且需要手动指向编译器(通过强制转换为 classes,基础或派生),它应该使用哪一个。


免责声明:这个答案是我试图扩展我对问题的评论,这似乎有帮助并且基于我链接的网站。非常欢迎编辑我的答案。