You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

varargs.xml 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <chapter id="varargs" xreflabel="Varargs">
  2. <title>Varargs</title>
  3. <sect1 id="varargs-inJava5" xreflabel="Varargs in Java 5">
  4. <title>Variable-length Argument Lists in Java 5</title>
  5. <para>
  6. Java 5 (and hence AspectJ 5) allows you to specify methods that take a
  7. variable number of arguments of a specified type. This is achieved using
  8. an ellipsis (...) in the method signature as shown:
  9. </para>
  10. <programlisting><![CDATA[
  11. public void foo(int i, String... strings) {
  12. }
  13. ]]></programlisting>
  14. <para>
  15. A method or constructor may take at most one variable length argument, and
  16. this must always be the last declared argument in the signature.
  17. </para>
  18. <sect2 id="calling-methods-and-constructors-with-variable-length-arguments" xreflabel="calling-methods-and-constructors-with-variable-length-arguments">
  19. <title>Calling Methods and Constructors with variable-length arguments</title>
  20. <para>
  21. A <emphasis>varargs</emphasis> method may be called with zero or more arguments
  22. in the variable argument position. For example, given the definition of
  23. <literal>foo</literal> above, the following calls are all legal:
  24. </para>
  25. <programlisting><![CDATA[
  26. foo(5);
  27. foo(5,"One String");
  28. foo(7,"One String","Two Strings");
  29. foo(3,"One String","Two Strings","Three Strings");
  30. ]]></programlisting>
  31. <para>A <emphasis>varargs</emphasis> parameter is treated as an array within the
  32. defining member. So in the body of <literal>foo</literal> we could write for example:
  33. </para>
  34. <programlisting><![CDATA[
  35. public void foo(int i, String... strings) {
  36. String[] someStrings = strings;
  37. // rest of method body
  38. }
  39. ]]></programlisting>
  40. <para>One consequence of this treatment of a varargs parameter as an array
  41. is that you can also call a varargs method with an array:</para>
  42. <programlisting><![CDATA[
  43. foo(7,new String[] {"One String","Two Strings"});
  44. ]]></programlisting>
  45. </sect2>
  46. </sect1>
  47. <sect1 id="varargs-in-pcds">
  48. <title>Using Variable-length arguments in advice and pointcut expressions</title>
  49. <para>AspectJ 5 allows variable-length arguments to be used for methods declared within
  50. aspects, and for inter-type declared methods and constructors, in accordance with the rules
  51. outlined in the previous section.</para>
  52. <para>
  53. AspectJ 5 also allows variable length arguments to be matched by pointcut expressions and
  54. bound as formals in advice.
  55. </para>
  56. <sect2 id="matching-signatures-based-on-variable-length-argument-types" xreflabel="matching-signatures-based-on-variable-length-argument-types">
  57. <title>Matching signatures based on variable length argument types</title>
  58. <para>
  59. Recall from the definition of signature patterns given in the chapter on
  60. annotations (<xref linkend="signaturePatterns"/>), that <literal>MethodPattern</literal>
  61. and <literal>ConstructorPattern</literal> are extended to allow a <literal>varargs</literal>
  62. pattern in the last argument position of a method or constructor signature.
  63. </para>
  64. <programlisting><![CDATA[
  65. FormalsPattern := '..' (',' FormalsPatternAfterDotDot)? |
  66. OptionalParensTypePattern (',' FormalsPattern)* |
  67. TypePattern '...'
  68. FormalsPatternAfterDotDot :=
  69. OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* |
  70. TypePattern '...'
  71. ]]></programlisting>
  72. <para>
  73. Method and constructor patterns are used in the <literal>call</literal>,
  74. <literal>execution</literal>, <literal>initialization</literal>,
  75. <literal>preinitialization</literal>, and <literal>withincode</literal>
  76. pointcut designators. Some examples of usage follow:
  77. </para>
  78. <variablelist>
  79. <varlistentry>
  80. <term>call(* org.xyz.*.*(int, String...))</term>
  81. <listitem>
  82. <para>
  83. Matches a call join point for a call to a method defined in the
  84. <literal>org.xyz</literal> package, taking an <literal>int</literal>
  85. and a <literal>String vararg</literal>.
  86. </para>
  87. </listitem>
  88. </varlistentry>
  89. <varlistentry>
  90. <term>execution(* org.xyz.*.*(Integer...))</term>
  91. <listitem>
  92. <para>
  93. Matches an execution join point for the execution of a method defined in the
  94. <literal>org.xyz</literal> package, taking an <literal>Integer vararg</literal>.
  95. </para>
  96. </listitem>
  97. </varlistentry>
  98. <varlistentry>
  99. <term>initialization(org.xyz.*.new((Foo || Goo)...))</term>
  100. <listitem>
  101. <para>
  102. Matches the initialization join point for the construction of an
  103. object in the <literal>org.xyz</literal> package via a constructor
  104. taking either a variable number of <literal>Foo</literal> parameters or
  105. a variable number of <literal>Goo</literal> parameters. (This example
  106. illustrating the use of a type pattern with ...).
  107. </para>
  108. </listitem>
  109. </varlistentry>
  110. </variablelist>
  111. <para>A variable argument parameter and an array parameter are treated as distinct
  112. signature elements, so given the method definitions:
  113. </para>
  114. <programlisting><![CDATA[
  115. void foo(String...);
  116. void bar(String[]);
  117. ]]></programlisting>
  118. <para>
  119. The pointcut <literal>execution(* *.*(String...))</literal> matches the execution join point
  120. for <literal>foo</literal>, but not <literal>bar</literal>. The pointcut
  121. <literal>execution(* *.*(String[]))</literal> matches the execution join point
  122. for <literal>bar</literal> but not <literal>foo</literal>.
  123. </para>
  124. </sect2>
  125. <sect2 id="exposing-variable-length-arguments-as-context-in-pointcuts-and-advice" xreflabel="exposing-variable-length-arguments-as-context-in-pointcuts-and-advice">
  126. <title>Exposing variable-length arguments as context in pointcuts and advice</title>
  127. <para>
  128. When a varargs parameter is used within the body of a method, it has
  129. an array type, as discussed in the introduction to this section. We follow the
  130. same convention when binding a varargs parameter via the <literal>args</literal>
  131. pointcut designator. Given a method
  132. </para>
  133. <programlisting><![CDATA[
  134. public void foo(int i, String... strings) {
  135. }
  136. ]]></programlisting>
  137. <para>
  138. The call or execution join points for <literal>foo</literal> will be matched
  139. by the pointcut <literal>args(int,String[])</literal>. It is not permitted
  140. to use the varargs syntax within an args pointcut designator - so you
  141. <emphasis>cannot</emphasis> write <literal>args(int,String...)</literal>.
  142. </para>
  143. <para>
  144. Binding of a varargs parameter in an advice statement is straightforward:
  145. </para>
  146. <programlisting><![CDATA[
  147. before(int i, String[] ss) : call(* foo(int,String...)) && args(i,ss) {
  148. // varargs String... argument is accessible in advice body through ss
  149. // ...
  150. }
  151. ]]></programlisting>
  152. <para>Since you cannot use the varargs syntax in the <literal>args</literal>
  153. pointcut designator, you also cannot use the varargs syntax to declare
  154. advice parameters.</para>
  155. <para>Note: the proposal in this section does not allow you to
  156. distinguish between a join point with a signature (int, String...)
  157. and a join point with a signature (int, String[]) based
  158. <emphasis>solely</emphasis> on the use of the <literal>args</literal>
  159. pointcut designator. If this distinction is required, <literal>args</literal>
  160. can always be coupled with <literal>call</literal> or
  161. <literal>execution</literal>.</para>
  162. </sect2>
  163. </sect1>
  164. </chapter>