我有一个类有两个这样的方法:
public class Dummy{
public void doIt(String arg1, File arg2, Writer... ctx){
// Do something very important...
}
public void doIt(String arg1, Writer... ctx){
// Do something else...
}
public static void main(String[] args){
new Dummy().doIt("Test", null);
}
}
我希望,编译器会给出错误,因为方法调用是不明确的。而是调用第二种方法。
在我们的例子中,ambigous方法是从数据库方法和稍后添加的varargs生成的。现在我们不知道如何避免方法调用的问题,如示例中所示。
是否有其他人有这个问题,并想知道如何解决它?
答案 0 :(得分:2)
我根据这个给出答案:
问题是如何找到这样的方法调用,第一个 应该调用方法(并且在我们更改代码之前) 生成器),但第二个被调用。
首先,正如已经指出的那样,Java编译器会发出有关此类方法用法的警告。它看起来像这样:
com / stack / undsprlbl / varargs / Main.java:10:警告:非varargs调用 最后一个参数的不精确参数类型的varargs方法;
可以轻松grep
- 来自javac
输出。
其次,你可以考虑在这些方面为你的代码编写一些自测:
Class cl = Ambiguity.class;
Method[] methods = cl.getDeclaredMethods();
Set<String> varargsMethods = new HashSet<String>();
for (Method method : methods) {
Class c[] = method.getParameterTypes();
if(c.length > 0)
{
Class last = c[c.length - 1];
if(last.isArray())
{
if(varargsMethods.contains(method.getName()))
System.out.println("Method " + cl.getName() + "#"+ method.getName() + " looks suspicious.");
else
varargsMethods.add(method.getName());
}
}
}
理解你应该迭代所有的课程,而不是直接提及。这个answer似乎是一种方法 - 在应用程序中获取所有包并检查它们。
此时您将有两个列表:
模棱两可的varargs方法用法列表
模棱两可的varargs方法列表。
通过跨越这两个,你可以找出你可能会遇到问题的地方。
接下来,我建议在添加第二种方法之前检查代码的版本,并查找第一种方法的所有用法。那些显然必须消除歧义,支持HEAD版本中的第一种方法。这样,我想,剩下这些电话的数量将非常有限。
答案 1 :(得分:0)
您的具体问题的答案是执行其他人所说的内容,并致电doIt("someString", null, null)
以使方法调用更具体。
话虽这么说,但真正的答案是重写方法以将Collection作为参数。使用varargs往往会导致比解决更多的问题。
答案 2 :(得分:0)
我建议创建一个明确的包装类,以防止意外滥用生成的类。
示例包装器:
public class NicerDummy{
Dummy dummy;
public NicerDummy(){
dummy = new Dummy();
}
public void doSomething(String arg1, Writer... ctx){
dummy.doIt(arg1, Writer);
}
public void doSomethingElse(String arg1, File arg2, Writer... ctx){
dummy.doIt(arg1, arg2, ctx);
}
}