Java Variable Argument Lists

本文深入探讨了Java中可变参数列表(Varargs)的使用,包括如何创建和使用可变参数列表,以及与自动装箱的关系。通过多个案例,展示了不同类型的可变参数列表的调用方式,并讨论了方法重载时的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

case 1: https://github.com/wangbingfeng/OnJava8-Examples/blob/master/housekeeping/VarArgs.java

// housekeeping/VarArgs.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Using array syntax to create variable argument lists

class A {}

public class VarArgs {
  static void printArray(Object[] args) {
    for (Object obj : args) System.out.print(obj + " ");
    System.out.println();
  }

  public static void main(String[] args) {
    printArray(new Object[] {47, (float) 3.14, 11.11});
    printArray(new Object[] {"one", "two", "three"});
    printArray(new Object[] {new A(), new A(), new A()});
  }
}
/* My Output:
47 3.14 11.11
one two three
A@6d06d69c A@7852e922 A@4e25154f
*/

printArray() takes an array of Object , then steps through the array using the for-in syntax and prints each one. The standard Java library classes produce sensible output, but the objects of the classes created here print the class name, followed by an @ sign and hexadecimal digits. Thus, the default behavior (if you don’t define a toString() method for your class) is to print the class name and the address of the object.

case 2: https://github.com/wangbingfeng/OnJava8-Examples/blob/master/housekeeping/NewVarArgs.java

// housekeeping/NewVarArgs.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Using array syntax to create variable argument lists

public class NewVarArgs {
  static void printArray(Object... args) {
    for (Object obj : args) System.out.print(obj + " ");
    System.out.println();
  }

  public static void main(String[] args) {
    // Can take individual elements:
    printArray(47, (float) 3.14, 11.11);
    printArray(47, 3.14F, 11.11);
    printArray("one", "two", "three");
    printArray(new A(), new A(), new A());
    // Or an array:
    printArray((Object[]) new Integer[] {1, 2, 3, 4});
    printArray(); // Empty list is OK
  }
}
/* Output:
47 3.14 11.11
47 3.14 11.11
one two three
A@15db9742 A@6d06d69c A@7852e922
1 2 3 4
*/

Notice the second-to-last line in the program, where an array of Integer (created using autoboxing) is cast to an Object array (to remove a compiler warning) and passed to printArray() . Clearly, the compiler sees this is already an array and performs no conversion on it. The last line of the program shows it’s possible to pass zero arguments to a vararg list.

case 3: https://github.com/wangbingfeng/OnJava8-Examples/blob/master/housekeeping/OptionalTrailingArguments.java

case 4: https://github.com/wangbingfeng/OnJava8-Examples/blob/master/housekeeping/VarargType.java

// housekeeping/VarargType.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

public class VarargType {
  static void f(Character... args) {
    System.out.print(args.getClass());
    System.out.println(" length " + args.length);
  }

  static void g(int... args) {
    System.out.print(args.getClass());
    System.out.println(" length " + args.length);
  }

  public static void main(String[] args) {
    f('a');
    f();
    g(1);
    g();
    System.out.println("int[]: " + new int[0].getClass());
  }
}
/* Output:
class [Ljava.lang.Character; length 1
class [Ljava.lang.Character; length 0
class [I length 1
class [I length 0
int[]: class [I
*/

The leading [ indicates this is an array of the type that follows. The I is for a primitive int ;  author created an array of int in the last line and printed its type. This verifies that using varargs does not depend on autoboxing, but it actually uses the primitive types. Varargs work harmoniously with autoboxing:

case 5: https://github.com/wangbingfeng/OnJava8-Examples/blob/master/housekeeping/AutoboxingVarargs.java

overload varargs

case 6: https://github.com/wangbingfeng/OnJava8-Examples/blob/master/housekeeping/OverloadingVarargs.java

// housekeeping/OverloadingVarargs.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

public class OverloadingVarargs {
  static void f(Character... args) {
    System.out.print("first");
    for (Character c : args) System.out.print(" " + c);
    System.out.println();
  }

  static void f(Integer... args) {
    System.out.print("second");
    for (Integer i : args) System.out.print(" " + i);
    System.out.println();
  }

  static void f(Long... args) {
    System.out.println("third");
  }

  public static void main(String[] args) {
    f('a', 'b', 'c');
    f(1);
    f(2, 1);
    f(0);
    f(0L); // good test
    // - f(); // Won't compile -- ambiguous
  }
}
/* Output:
first a b c
second 1
second 2 1
second 0
third
*/

case 7: https://github.com/wangbingfeng/OnJava8-Examples/blob/master/housekeeping/OverloadingVarargs2.java

// housekeeping/OverloadingVarargs2.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// {WillNotCompile}

public class OverloadingVarargs2 {
  static void f(float i, Character... args) {
    System.out.println("first");
  }

  static void f(Character... args) {
    System.out.print("second");
  }

  public static void main(String[] args) {
    f(1, 'a');
    f('a', 'b'); // compile error
  }
}

My error prompt:

OverloadingVarargs2.java:16: error: reference to f is ambiguous
    f('a', 'b');
    ^
  both method f(float,Character...) in OverloadingVarargs2 and method f(Character...) in OverloadingVarargs2 match
1 error

If you give both methods a non-vararg argument, it works:

case 8: https://github.com/wangbingfeng/OnJava8-Examples/blob/master/housekeeping/OverloadingVarargs3.java

// housekeeping/OverloadingVarargs3.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

public class OverloadingVarargs3 {
  static void f(float i, Character... args) {
    System.out.println("first");
  }

  static void f(char c, Character... args) {
    System.out.println("second");
    for (Character c1 : args) {
      System.out.print(c1 + " ");
    }
    System.out.println(args);
  }

  public static void main(String[] args) {
    f(1, 'a');
    f('a', 'b', 'c');
  }
}
/* My Output:
first
second
b c [Ljava.lang.Character;@6d06d69c
*/

As a rule of thumb, only use a variable argument list on one version of an overloaded method. Or consider not doing it at all.

references:

1. On Java 8 - Bruce Eckel

180 warnings generated. [ 0% 11/1154] target Java: framework (out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes) FAILED: /bin/bash out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes-full-debug.jar.rsp frameworks/base/core/java/android/content/pm/PackageParser.java:2794: error: cannot find symbol if ("com.dangbei.tvlauncher".equals(pkg.packageName)) { ^ symbol: variable pkg location: class PackageParser frameworks/base/core/java/android/content/pm/PackageParser.java:2795: error: cannot find symbol for (Activity a : pkg.activities) { ^ symbol: variable pkg location: class PackageParser frameworks/base/core/java/android/content/pm/PackageParser.java:2797: error: no suitable constructor found for IntentFilter(String,String,String) a.intents.add(new IntentFilter( ^ constructor IntentFilter.IntentFilter() is not applicable (actual and formal argument lists differ in length) constructor IntentFilter.IntentFilter(String) is not applicable (actual and formal argument lists differ in length) constructor IntentFilter.IntentFilter(String,String) is not applicable (actual and formal argument lists differ in length) constructor IntentFilter.IntentFilter(IntentFilter) is not applicable (actual and formal argument lists differ in length) constructor IntentFilter.IntentFilter(Parcel) is not applicable (actual and formal argument lists differ in length) Note: Some input files use or override a deprecated API. Note: Recompile with -Xlint:deprecation for details. Note: Some input files use unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 3 errors ninja: build stopped: subcommand failed. build/core/ninja.mk:148: recipe for target 'ninja_wrapper' failed make: *** [ninja_wrapper] Error 1 #### make failed to build some targets (42 seconds) ####
最新发布
07-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值