Parses the variable length parameter list of Java and the points to note when using it

  • 2020-05-07 19:36:55
  • OfStack

Java variable-parameter list


class A {}

Since all classes inherit from Object, you can take the Object array as an argument:


public class parameter {
  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[] {
        new Integer(47), new Float(3.14), new Double(11.11)
    });
    printArray(new Object[]{"one", "two", "there"});
    printArray(new Object[]{new A(), new A(), new A()});
  }
}

For Java SE5 later versions with added features, write:


public class parameter {
  public static void printArray(Object... args){
    for(Object obj : args){
      System.out.print(obj + " ");
    }
    System.out.println();
  }
  
  public static void main(String[] args){
    printArray(new Integer(47), new Float(3.14), new Double(11.11));
    printArray(47, 3.14F, 11.11);
    printArray("one", "two", "three");
    printArray(new A(), new A(), new A());
    printArray((Object[]) new Integer[]{1, 2, 3, 4});
    printArray();
  }
}

You can use the Object argument list:


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

This is a feature introduced in Java 5, which is useful if the number of arguments to be received by a method is uncertain.

For example, where an IO operation is involved, there are basically at least two streams that need to be closed: input and output, and I like to wrap the operation of stream closure into the following method, so that multiple streams can be closed with only one call.


public static void closeSilent(Closeable... closeables) {
   for (Closeable closeable : closeables) {
     if (closeable != null) {
        try {
          closeable.close();
        } catch (IOException ignored) {
        }
     }
   }
}

This is the only place I think this feature is suitable for use. It has the following characteristics:

These parameters have the same type;
The number of parameters is uncertain, and each one is optional.
These parameters are all used for one purpose, such as execution close.
The Java variable-length argument list can only be placed at the end of the method argument list.


Java variable length parameter list implementation

The implementation of the Java variable-length parameter list is passed by the compiler, which encapsulates these parameters into an array.

For example, the signature of the method above is actually closeSilent(Closeable[] closeables) void.

on pit

One method was called by A, B, A and B. In September, I needed to add one parameter to A. At that time, my mind was crazy and I decided to use the variable length parameter list.

Recently, B was required to add two new parameters here, so continue to add parameters to the method's parameter list. These parameters are of different types, so the variable length parameter list is declared as Object.

The first pit is in this method to take variable length parameter elements, did not consider that some parameters are not passed, directly burst array offside exception. Immediately, I felt that the variable length parameter list was not good, so I did not use it, and changed to the regular fixed form of parameter passing.

After the change, in the test environment was tested all right. After replacing several classes in the production environment, the result is an error, the method cannot be found, 1 look at the method signature, it is still an array, not replaced to. From the source, that call does not need to change the place, so did not think to replace; Since the test environment was fully packaged, there were no problems.

Method signatures are determined at compile time, and the source code level does not seem to need to change does not mean that the compiled class does not need to be replaced.

In fact, also heard before, in this case, the source code of 1 constant value changed, only replaced the definition of the constant class file, not all references to the constant class file recompile replace, resulting in puzzling problems. The problem with method signatures is essentially the same.


Related articles: