使用可变参数的方法存在不明确的 Java Bug?

问题描述 投票:0回答:3

我有一个类,有两个这样的方法:

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);
  }
}

我希望编译器会给出错误,因为方法调用不明确。相反,会调用第二种方法。

在我们的例子中,不明确的方法是从数据库方法和稍后添加的可变参数生成的。现在我们不知道如何避免像示例中那样的方法调用问题。

其他人有这个问题并知道如何解决吗?

java variadic-functions ambiguous
3个回答
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 似乎是一种方法 --- 获取应用程序中的所有包并检查它们。

此时您将有两个列表:

  1. 不明确的可变参数方法用法列表

  2. 不明确的可变参数方法列表。

通过交叉这两者,您可以找出可能会出现问题的地方。

接下来,我建议检查添加第二个方法之前的代码版本,并找到第一个方法的所有用法。显然必须消除这些歧义,以支持 HEAD 版本中的第一种方法。我想,这样一来,剩下的呼叫数量就会相当有限。


0
投票
你具体问题的答案是按照别人说的去做,调用

doIt("someString", null, null)

,让方法调用更具体。

话虽这么说,真正的答案是重写方法以将 Collection 作为参数。使用可变参数往往会导致比它解决的问题更多的问题。


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); } }
    
© www.soinside.com 2019 - 2024. All rights reserved.