| <html><head> | |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |
| <title>Inter-type Declarations</title><link rel="stylesheet" href="aspectj-docs.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.44"><link rel="home" href="index.html" title="The AspectJTM 5 Development Kit Developer's Notebook"><link rel="up" href="ataspectj.html" title="Chapter 9. An Annotation Based Development Style"><link rel="previous" href="ataspectj-pcadvice.html" title="Pointcuts and Advice"><link rel="next" href="ataspectj-declare.html" title="Declare statements"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Inter-type Declarations</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ataspectj-pcadvice.html">Prev</a> </td><th width="60%" align="center">Chapter 9. An Annotation Based Development Style</th><td width="20%" align="right"> <a accesskey="n" href="ataspectj-declare.html">Next</a></td></tr></table><hr></div><div class="sect1"><a name="ataspectj-itds"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="ataspectj-itds"></a>Inter-type Declarations</h2></div></div><p> | |
| Inter-type declarations are challenging to support using an annotation style. | |
| It's very important to preserve the same semantics between the code style | |
| and the annotation style. We also want to support compilation of a large set | |
| of @AspectJ applications using a standard Java 5 compiler. For these reasons, | |
| the 1.5.0 release of AspectJ 5 only supports inter-type declarations | |
| backed by interfaces when using the annotation style - | |
| which means it is not possible to | |
| introduce constructors or fields, as it would not be not possible to call | |
| those unless already woven and available on a binary form. | |
| </p><p> | |
| Consider the following aspect: | |
| </p><pre class="programlisting"> | |
| public aspect MoodIndicator { | |
| public interface Moody {}; | |
| private Mood Moody.mood = Mood.HAPPY; | |
| public Mood Moody.getMood() { | |
| return mood; | |
| } | |
| declare parents : org.xyz..* implements Moody; | |
| before(Moody m) : execution(* *.*(..)) && this(m) { | |
| System.out.println("I'm feeling " + m.getMood()); | |
| } | |
| } | |
| </pre><p> | |
| This declares an interface | |
| <tt>Moody</tt> | |
| , and then makes two | |
| inter-type declarations on the interface - a field that is private to the | |
| aspect, and a method that returns the mood. Within the body of the inter-type | |
| declared method | |
| <tt>getMoody</tt> | |
| , the type of | |
| <tt>this</tt> | |
| is | |
| <tt>Moody</tt> | |
| (the target type of the inter-type declaration). | |
| </p><p>Using the annotation style this aspect can be written: | |
| </p><pre class="programlisting"> | |
| @Aspect | |
| public class MoodIndicator { | |
| // this interface can be outside of the aspect | |
| public interface Moody { | |
| Mood getMood(); | |
| }; | |
| // this implementation can be outside of the aspect | |
| public static class MoodyImpl implements Moody { | |
| private Mood mood = Mood.HAPPY; | |
| public Mood getMood() { | |
| return mood; | |
| } | |
| } | |
| // the field type must be the introduced interface. It can't be a class. | |
| @DeclareParents(value="org.xzy..*",defaultImpl=MoodyImpl.class) | |
| private Moody implementedInterface; | |
| @Before("execution(* *.*(..)) && this(m)") | |
| void feelingMoody(Moody m) { | |
| System.out.println("I'm feeling " + m.getMood()); | |
| } | |
| } | |
| </pre><p> | |
| This is very similar to the mixin mechanism supported by AspectWerkz. The | |
| effect of the | |
| <tt>@DeclareParents</tt> | |
| annotation is equivalent to | |
| a declare parents statement that all types matching the type pattern implement | |
| the given interface (in this case Moody). | |
| Each method declared in the interface is treated as an inter-type declaration. | |
| Note how this scheme operates within the constraints | |
| of Java type checking and ensures that | |
| <tt>this</tt> | |
| has access | |
| to the exact same set of members as in the code style example. | |
| </p><p> | |
| Note that it is illegal to use the @DeclareParents annotation on an aspect' field of a non-interface type. | |
| The interface type is the inter-type declaration contract that dictates | |
| which methods are declared on the target type. | |
| </p><pre class="programlisting"> | |
| // this type will be affected by the inter-type declaration as the type pattern matches | |
| package org.xyz; | |
| public class MoodTest { | |
| public void test() { | |
| // see here the cast to the introduced interface (required) | |
| Mood mood = ((Moody)this).getMood(); | |
| ... | |
| } | |
| } | |
| </pre><p>The <tt>@DeclareParents</tt> annotation can also be used without specifying | |
| a <tt>defaultImpl</tt> value (for example, | |
| <tt>@DeclareParents("org.xyz..*")</tt>). This is equivalent to a | |
| <tt>declare parents ... implements</tt> clause, and does <span class="emphasis"><i>not</i></span> | |
| make any inter-type declarations for default implementation of the interface methods. | |
| </p><p> | |
| Consider the following aspect: | |
| </p><pre class="programlisting"> | |
| public aspect SerializableMarker { | |
| declare parents : org.xyz..* implements Serializable; | |
| } | |
| </pre><p>Using the annotation style this aspect can be written: | |
| </p><pre class="programlisting"> | |
| @Aspect | |
| public class SerializableMarker { | |
| @DeclareParents("org.xyz..*") | |
| Serializable implementedInterface; | |
| } | |
| </pre><p> | |
| If the interface defines one or more operations, and these are not implemented by | |
| the target type, an error will be issued during weaving. | |
| </p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ataspectj-pcadvice.html">Prev</a> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right"> <a accesskey="n" href="ataspectj-declare.html">Next</a></td></tr><tr><td width="40%" align="left">Pointcuts and Advice </td><td width="20%" align="center"><a accesskey="u" href="ataspectj.html">Up</a></td><td width="40%" align="right"> Declare statements</td></tr></table></div></body></html> |