== Varargs [[varargs-inJava5]] === Variable-length Argument Lists in Java 5 Java 5 (and hence AspectJ 5) allows you to specify methods that take a variable number of arguments of a specified type. This is achieved using an ellipsis (`...`) in the method signature as shown: [source, java] .... public void foo(int i, String... strings) {} .... A method or constructor may take at most one variable length argument, and this must always be the last declared argument in the signature. ==== Calling Methods and Constructors with variable-length arguments A _varargs_ method may be called with zero or more arguments in the variable argument position. For example, given the definition of `foo` above, the following calls are all legal: [source, java] .... foo(5); foo(5,"One String"); foo(7,"One String","Two Strings"); foo(3,"One String","Two Strings","Three Strings"); .... A _varargs_ parameter is treated as an array within the defining member. So in the body of `foo` we could write for example: [source, java] .... public void foo(int i, String... strings) { String[] someStrings = strings; // rest of method body } .... One consequence of this treatment of a varargs parameter as an array is that you can also call a varargs method with an array: [source, java] .... foo(7,new String[] {"One String","Two Strings"}); .... [[varargs-in-pcds]] === Using Variable-length arguments in advice and pointcut expressions AspectJ 5 allows variable-length arguments to be used for methods declared within aspects, and for inter-type declared methods and constructors, in accordance with the rules outlined in the previous section. AspectJ 5 also allows variable length arguments to be matched by pointcut expressions and bound as formals in advice. ==== Matching signatures based on variable length argument types Recall from the definition of signature patterns given in the chapter on annotations (xref:annotations.adoc#signaturePatterns[Signature Patterns]), that `MethodPattern` and `ConstructorPattern` are extended to allow a `varargs` pattern in the last argument position of a method or constructor signature. [source, text] .... FormalsPattern := '..' (',' FormalsPatternAfterDotDot)? | OptionalParensTypePattern (',' FormalsPattern)* | TypePattern '...' FormalsPatternAfterDotDot := OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* | TypePattern '...' .... Method and constructor patterns are used in the `call`, `execution`, `initialization`, `preinitialization`, and `withincode` pointcut designators. Some examples of usage follow: `call(* org.xyz.*.*(int, String...))`:: Matches a call join point for a call to a method defined in the `org.xyz` package, taking an `int` and a `String` _vararg_. `execution(* org.xyz.*.*(Integer...))`:: Matches an execution join point for the execution of a method defined in the `org.xyz` package, taking an `Integer` _vararg_. `initialization(org.xyz.*.new((Foo || Goo)...))`:: Matches the initialization join point for the construction of an object in the `org.xyz` package via a constructor taking either a variable number of `Foo` parameters or a variable number of `Goo` parameters. (This example illustrating the use of a type pattern with `...`). A variable argument parameter and an array parameter are treated as distinct signature elements, so given the method definitions: [source, java] .... void foo(String...); void bar(String[]); .... The pointcut `execution(* *.*(String...))` matches the execution join point for `foo`, but not `bar`. The pointcut `execution(* *.*(String[]))` matches the execution join point for `bar` but not `foo`. ==== Exposing variable-length arguments as context in pointcuts and advice When a varargs parameter is used within the body of a method, it has an array type, as discussed in the introduction to this section. We follow the same convention when binding a varargs parameter via the `args` pointcut designator. Given a method [source, java] .... public void foo(int i, String... strings) {} .... The call or execution join points for `foo` will be matched by the pointcut `args(int,String[])`. It is not permitted to use the varargs syntax within an args pointcut designator - so you _cannot_ write `args(int,String...)`. Binding of a varargs parameter in an advice statement is straightforward: [source, java] .... before(int i, String[] ss) : call(* foo(int,String...)) && args(i,ss) { // varargs String... argument is accessible in advice body through ss // ... } .... Since you cannot use the varargs syntax in the `args` pointcut designator, you also cannot use the varargs syntax to declare advice parameters. Note: the proposal in this section does not allow you to distinguish between a join point with a signature `(int, String...)` and a join point with a signature `(int, String[])` based _solely_ on the use of the `args` pointcut designator. If this distinction is required, `args` can always be coupled with `call` or `execution`.