首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我可以将数组作为参数传递给Java中带有变量参数的方法吗?

我可以将数组作为参数传递给Java中带有变量参数的方法吗?
EN

Stack Overflow用户
提问于 2018-10-30 08:21:35
回答 2查看 0关注 0票数 0

我希望能够创建一个像这样的函数:

代码语言:javascript
复制
class A {
  private String extraVar;
  public String myFormat(String format, Object ... args){
    return String.format(format, extraVar, args);
  }
}

这里的问题是在方法中args被处理,因此是单个参数,而我希望每个in 都作为新参数传递。既然也是一个带有变量参数的方法,这应该是可能的。Object[]myFormatString.formatObjectargsString.format

如果这是不可能的,有没有像这样的方法String.format(String format, Object[] args)?在这种情况下,我可以在前面加上extraVarargs使用新的数组,并把它传递给该方法。

EN

回答 2

Stack Overflow用户

发布于 2018-10-30 16:50:37

我遇到了同样的问题。

代码语言:javascript
复制
String[] arr= new String[] { "A", "B", "C" };
Object obj = arr;

然后通过obj作为varargs论证。有效。

票数 0
EN

Stack Overflow用户

发布于 2018-10-30 17:25:29

是的,a T...只是a的语法糖T[]

JLS 8.4.1格式参数

列表中的最后一个形式参数是特殊的; 它可以是一个可变的arity参数,由类型后面的省略号表示。 如果最后一个形式参数是类型的变量arity参数T,则认为它定义了类型的形式参数T[]。然后该方法是可变的arity方法。否则,它是一种固定的arity方法。变量arity方法的调用可能包含比形式参数更多的实际参数表达式。将评估与变量arity参数之前的形式参数不对应的所有实际参数表达式,并将结果存储到将传递给方法调用的数组中。

这是一个例子来说明:

代码语言:javascript
复制
public static String ezFormat(Object... args) {
    String format = new String(new char[args.length])
        .replace("\0", "[ %s ]");
    return String.format(format, args);
}
public static void main(String... args) {
    System.out.println(ezFormat("A", "B", "C"));
    // prints "[ A ][ B ][ C ]"
}

是的,上面的main方法是有效的,因为再次,String...只是String[]。此外,因为数组是协变的,a String[]是a Object[],所以你也可以调用ezFormat(args)任何一种方式。

也可以看看

Varargs陷入困境#1:传球 null

如何解决varargs是非常复杂的,有时它会做一些可能让你感到惊讶的事情。

考虑这个例子:

代码语言:javascript
复制
static void count(Object... objs) {
    System.out.println(objs.length);
}

count(null, null, null); // prints "3"
count(null, null); // prints "2"
count(null); // throws java.lang.NullPointerException!!!

由于可变参数如何解决,最后的语句调用objs = null,这当然会导致NullPointerExceptionobjs.length。如果要为nullvarargs参数提供一个参数,可以执行以下任一操作:

代码语言:javascript
复制
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"

相关问题

以下是人们在处理varargs时提出的一些问题的示例:

Vararg陷入困境#2:增加额外的论点

正如您所知,以下内容并非“有效”:

代码语言:javascript
复制
    String[] myArgs = { "A", "B", "C" };
    System.out.println(ezFormat(myArgs, "Z"));
    // prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"

由于varargs的工作方式,ezFormat实际上得到2个参数,第一个是a String[],第二个是a String。如果您将数组传递给varargs,并且希望将其元素识别为单独的参数,并且还需要添加额外的参数,那么您别无选择,只能创建另一个容纳额外元素的数组

以下是一些有用的辅助方法:

代码语言:javascript
复制
static <T> T[] append(T[] arr, T lastElement) {
    final int N = arr.length;
    arr = java.util.Arrays.copyOf(arr, N+1);
    arr[N] = lastElement;
    return arr;
}
static <T> T[] prepend(T[] arr, T firstElement) {
    final int N = arr.length;
    arr = java.util.Arrays.copyOf(arr, N+1);
    System.arraycopy(arr, 0, arr, 1, N);
    arr[0] = firstElement;
    return arr;
}

现在您可以执行以下操作:

代码语言:javascript
复制
    String[] myArgs = { "A", "B", "C" };
    System.out.println(ezFormat(append(myArgs, "Z")));
    // prints "[ A ][ B ][ C ][ Z ]"

    System.out.println(ezFormat(prepend(myArgs, "Z")));
    // prints "[ Z ][ A ][ B ][ C ]"

Varargs陷阱#3:传递一系列原语

它没有“工作”:

代码语言:javascript
复制
    int[] myNumbers = { 1, 2, 3 };
    System.out.println(ezFormat(myNumbers));
    // prints "[ [I@13c5982 ]"

Varargs仅适用于引用类型。自动装箱不适用于基元数组。以下作品:

代码语言:javascript
复制
    Integer[] myNumbers = { 1, 2, 3 };
    System.out.println(ezFormat(myNumbers));
    // prints "[ 1 ][ 2 ][ 3 ]"
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100006192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档