0

嗨,我在 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))));

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

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

我该如何解决这个错误?

4

1 回答 1

2

解决方案是在最后一行units转换为:PatchingChain

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

有什么问题?

我查看了Soot源代码。PatchingChain扩展和它的AbstractCollection标题看起来像这样:

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>

所以我们有带有类型参数 section 的基类和E带有 section 的派生类E extends Unit

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


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

于 2016-04-04T13:13:20.887 回答