【问题标题】:How to forward a parameterlist如何转发参数列表
【发布时间】:2017-11-27 12:05:40
【问题描述】:

我已经声明了一个接口Listable、一个包含ListableNode 和一个包含节点的SinglyLinkedListSinglyLinkedList 包含一个search() 方法,它利用了Listable 中的matches() 方法。我希望Listable 尽可能通用,所以matches() 中的参数数量应该是任意的。 search() 返回一个新的 SinglyLinkedList,仅包含匹配的 this 元素。

看下面的实现:

interface Listable {
    // ...
    boolean matches(Object... matchesArgs);
    // ...
}

class Node {
   Listable data;
   Node next;
}

class SinglyLinkedList {
    // ...
    public SinglyLinkedList search(Object... searchArgs) {
        // ...
        somewhere: [someNode].data.matches(searchArgs)
        // ...
    }
    // ...
}

这不起作用,因为matchesArgs 只有一个元素:数组searchArgs。我希望它等于searchArgs,而不是[searchArgs]

我不想在matches() 的实现中解压缩数组,因为这将需要在您使用matches() 时传递参数数组,并且它还会尝试在未创建的地方处理问题。

在我看来,问题是searchArgs 在转发到matches() 时被打包到另一个数组中。我不想传递这个数组,而是将它的元素作为参数传递。

有没有办法在 Java 中做到这一点?

【问题讨论】:

  • 您的代码会发出警告,因为它不明确。这种歧义的根源是在您的可变参数方法中使用了Object。考虑对您的系统进行建模,以使您的方法不会收到糟糕的Object 类型。

标签: java parameter-passing variadic-functions


【解决方案1】:

我不确定将searchArgs 作为参数传递给matches 是否会导致该参数被另一个数组包装。拿这个示例代码:

import java.util.Arrays;

public class HelloWorld {
    public static void main(String[] args) {
        doThat(1, 2, 3, 4, 5);
    }

    public static void doThat(Object... varargs) {
        doThis(varargs);
    }

    public static void doThis(Object... varargs) {
        System.out.println(Arrays.toString(varargs));
    }
}

输出是预期的[1, 2, 3, 4, 5]

【讨论】:

  • 你说得对……我实际上在调用 search() 时忘记了一个参数……当我看到错误时(我已经实现了一些异常匹配),我立即想到了所描述的问题,而不是先调用 search() 时检查我的参数......这很尴尬。谢谢!
  • 一点也不尴尬。一切顺利!
【解决方案2】:

这需要在你使用matches()时传递一个参数数组

但是您在方法的签名中指定它接受可变长度的数组。在调用代码时,没有什么可以阻止您传递一个或一些值。在matches方法内部,它将是一个数组

【讨论】:

  • 我已经编辑了问题以使问题更清楚...我知道matchesArgs 是一个数组,但问题是它只有一个元素:数组searchArgs。我希望它等于 searchArgs
【解决方案3】:

据我了解您的问题,您的问题可以简化为:

public class HelloWorld {
  public static void main(String[] args) {
    test(1, 2, 3);
    test(new Integer [] {1, 2, 3});
  }

  public static void test(Object... args) {
    System.out.println("Length: " + args.length);
  }
}

此代码发出以下警告:

警告:可变参数方法的非可变参数调用,最后一个参数的参数类型不准确

问题很清楚。 Java 无法决定该数组是展开还是作为第一个参数传递。

你可以通过使用正确的类型来解决这个问题。

public class HelloWorld {
  public static void main(String[] args) {
    test(1, 2, 3);
    test(new Integer [] {1, 2, 3});
  }
                       // here!
  public static void test(Integer... args) {
    System.out.println("Length: " + args.length);
  }
}

现在这段代码没有歧义并且编译得很好。输出是:

Length: 3
Length: 3

你应该好好利用类型系统。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 2018-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 2017-10-01
    相关资源
    最近更新 更多