diff options
author | acolyer <acolyer> | 2004-11-24 19:57:59 +0000 |
---|---|---|
committer | acolyer <acolyer> | 2004-11-24 19:57:59 +0000 |
commit | acbb4e5b1a7c107d0f3897431b15a78d9026c381 (patch) | |
tree | 27bace6b8184de939ece3f89b6c354a31aa97a94 /docs/adk15ProgGuideDB/covariance.xml | |
parent | 639b61b6a7f5cd090137340c35c2f4ae355ad538 (diff) | |
download | aspectj-acbb4e5b1a7c107d0f3897431b15a78d9026c381.tar.gz aspectj-acbb4e5b1a7c107d0f3897431b15a78d9026c381.zip |
more updates to 1.5 design
Diffstat (limited to 'docs/adk15ProgGuideDB/covariance.xml')
-rw-r--r-- | docs/adk15ProgGuideDB/covariance.xml | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/docs/adk15ProgGuideDB/covariance.xml b/docs/adk15ProgGuideDB/covariance.xml index d182e157e..4e1e2f8de 100644 --- a/docs/adk15ProgGuideDB/covariance.xml +++ b/docs/adk15ProgGuideDB/covariance.xml @@ -2,5 +2,179 @@ <title>Covariance</title> + <sect1 id="covariance-inJava5"> + <title>Covariance in Java 5</title> + + <para> + Java 5 (and hence AspectJ 1.5) allows you to narrow the return type + in an overriding method. For example: + </para> + + <programlisting><![CDATA[ + class A { + public A whoAreYou() {...} + } + + class B extends A { + // override A.whoAreYou *and* narrow the return type. + public B whoAreYou() {...} + } + ]]></programlisting> + + </sect1> + + <sect1> + <title>Covariant methods and Join Point matching</title> + + <para>The join point matching rules for <literal>call</literal> + and <literal>execution</literal> pointcut designators are extended + to match against covariant methods.</para> + + <para> + Given the classes <literal>A</literal> and <literal>B</literal> + as defined in the previous section, and the program fragment + </para> + + <programlisting><![CDATA[ + A a = new A(); + B b = new B(); + a.whoAreYou(); + b.whoAreYou(); + ]]></programlisting> + + <para>Then the call and execution join points for <literal>whoAreYou</literal> + are matched as follows:</para> + + <variablelist> + + <varlistentry> + <term>call(* whoAreYou())</term> + <listitem> + <para>Matches both calls, (since it places no constraint on the + return type of the join point signature). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>call(* A.whoAreYou())</term> + <listitem> + <para>Matches both calls, (since the original declaring type + of <literal>whoAreYou</literal> is <literal>A</literal>). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>call(A whoAreYou())</term> + <listitem> + <para>Matches both calls, (since the signature of + <literal>whoAreYou</literal>) in the original declaring type + has a return type of <literal>A</literal>). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>call(A B.whoAreYou())</term> + <listitem> + <para>Does not match anything - the signature of <literal>whoAreYou</literal> + as overriden in <literal>B</literal> has a return type of + <literal>B</literal>, not <literal>A</literal>. A lint warning is + given for the call <literal>a.whoAreYou()</literal> ("does not match + because declaring type is A, if match required use target(B)"). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>call(A+ B.whoAreYou())</term> + <listitem> + <para>Matches the call to <literal>b.whoAreYou()</literal> since + the return type <literal>B</literal> in the method signature + is matched by the type pattern <literal>A+</literal>. A lint warning is + given for the call <literal>a.whoAreYou()</literal> ("does not match + because declaring type is A, if match required use target(B)"). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>call(B A.whoAreYou())</term> + <listitem> + <para>Does not match anything - there is no method declared in + <literal>A</literal> with a return type of <literal>B</literal>. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>call(B whoAreYou())</term> + <listitem> + <para>Matches the call to <literal>b.whoAreYou()</literal> only. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>call(B B.whoAreYou())</term> + <listitem> + <para>Matches the call to <literal>b.whoAreYou()</literal> only. + </para> + </listitem> + </varlistentry> + + </variablelist> + + <para>The rule for signature matching at call and execution join points + is unchanged from AspectJ 1.2: a call or execution pointcut matches if + the signature pattern matches at least one of the signatures of the + join point, and if the most-specific matched signature is also matched + by any modifier pattern or annotation pattern that may be present.</para> + + <para>For a call or execution join point, the signatures of a join point + for the call or execution of a method <literal>Rtype T.m(params)</literal> + are determined as follows:</para> + <itemizedlist> + <listitem> + If <literal>m(params)</literal> is defined in <literal>T</literal>, + then the signature of <literal>m(params)</literal> in <literal>T</literal> is + a signature of the join point: <literal>Rtype T.m(params)</literal>. + If <literal>T</literal> does not + provide its own definition of <literal>m</literal>, then the signature + <literal>Rtype' T.m(params)</literal> + is a signature of the join point, where <literal>Rtype'</literal> is the return type of + the definition of <literal>m</literal> inherited by <literal>T</literal>. + </listitem> + <listitem> + For each super-type <literal>S</literal> of <literal>T</literal> that is a valid receiver + for a call to <literal>m</literal>, then the signature of <literal>m(params)</literal> in + <literal>S</literal> is a signature + of the join point: <literal>Rtype S.m(params)</literal>. + If <literal>S</literal> does not provide its + own definition of <literal>m</literal>, then the signature + <literal>Rtype' S.m(params)</literal> is a + signature of the join point, where <literal>Rtype'</literal> is the return type of the + definition of <literal>m</literal> inherited by <literal>S</literal>. + </listitem> + </itemizedlist> + + <para>A call to <literal>b.whoAreYou()</literal> has the join point signatures + </para> + + <itemizedlist> + <listitem>B B.whoAreYou()</listitem> + <listitem>A A.whoAreYou()</listitem> + </itemizedlist> + + <para>Following the rule given, it is easy to see why for example + <literal>call(B A.whoAreYou())</literal> does not match anything as + this pattern matches neither of the signatures at the join point. In + contrast, the pointcut expression <literal>call(A+ B.whoAreYou())</literal> + does match the call to <literal>b.whoAreYou()</literal> because it matches + the second of the signatures at the join point.</para> + </sect1> + + </chapter> |