Home  >  Article  >  Java  >  Parsing Java's variable-length parameter list and points to note when using it

Parsing Java's variable-length parameter list and points to note when using it

高洛峰
高洛峰Original
2017-01-19 15:13:041441browse

Java Variable Parameter List

class A {}

Since all classes inherit from Object, you can use the Object array as a parameter:

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 and later versions that have added features, you can write like this:

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 parameter list that Object thinks:

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. If the number of parameters to be received by a method is uncertain, then this feature can come in handy.

For example, where IO operations are involved, at least two streams need to be closed: input and output. I like to encapsulate the stream closing operation into the following method, so that multiple streams can be closed with just one call. A flow.

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

This is the only place where I think this feature is suitable to be used, with the following characteristics:

These parameters have the same type;
The number of parameters is uncertain , each one is optional;
The purpose of these parameters is the same, for example, the above are all execution shutdown.
Java variable-length parameter list can only be placed at the end of the method parameter list.


Implementation of Java variable-length parameter list

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

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

Stepping into the pit

There is a method that is called by A and B in two places, A and B. In September, I needed to add a parameter at A. At that time, my brain went crazy and I decided to use Regarding the variable-length parameter list, I thought it would be simpler without changing the parameter B, so the pit was buried.

Recently asked B to add two new parameters here, then continue to add parameters to the parameter list of the method. The types of these parameters are different, so the variable-length parameter list is declared as Object type.

The first pitfall is that when fetching the elements of variable-length parameters in this method, it is not considered that some parameters are not passed, and an array offside exception is directly caused. Immediately I felt that the variable length parameter list was not good, so I didn’t need it and changed it to regular fixed-form parameter passing.

After the modification, it was no problem when tested in the test environment. After replacing several classes in the production environment, an error was reported and the method could not be found. When I looked at the method signature, it was still an array and it was not replaced. Judging from the source code, the calling place does not need to be changed, so I did not expect to replace it; since the test environment is fully packaged, there will be no problems.

The signature of the method is determined during compilation. If the source code level does not need to be changed, it does not mean that the compiled class does not need to be replaced.

In fact, I have heard before that in this case of irregular contracting, after changing the value of a constant in the source code, only the class file that defines the constant is replaced, without all references to the constant being replaced. The class files are recompiled and replaced, causing inexplicable problems. It's essentially the same problem as the method signature situation.

For more related articles on parsing Java’s variable-length parameter list and precautions when using it, please pay attention to the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn