Hi Fernando. I think the confusion here arises from a misunderstanding of the subtyping relationship with generics on your part.
ArrayList<X> is always a subtype of List<X> for some concrete type X, and therefore a match is generally possible and AspectJ determines whether or not to match using a runtime check. *However* no List<Y> is ever subtype of a List<X> for any two different concrete types X and Y, regardless of whether Y is a subtype of X! As a consequence, also List<Integer> cannot possibly be an ArrayList<Number>. What surprises me is the fact that the first advice in BC matches. Actually this should not match either, I believe, because also a List<Integer> can never be a List<Number>. I am not sure... could this have to do with type erasure? Eric 2008/11/1 Fernando Rubbo <[EMAIL PROTECTED]>: > Hi all, > > I have a question about args(..) and after(..) returning(..) construction > semantics when generic types are applied. > Actually, it is not clear for me how it is working and why it is working > this way. Let me show an example to help to depict my thoughts. > > class C{ > void m(List<Integer> e){} > } > > aspect AC { > void around():execution(* C.*(..)) && args(List<Integer>) {} // Matchs > C.m > void around():execution(* C.*(..)) && args(ArrayList<Integer>) {} // > Unchecked match C.m - uses rRuntime check > } > > In this simple example, it is easy to notice that both advices will match > the method C.m. Note that the second one will make a runtime test to check > if the method caller has passed, as a parameter, an ArrayList object. Since > actual type parameters are erasured during compile-time, the AspectJ > compiler just warn the programmer that this is an unchecked match (however, > it is easy to notice that in this case it will never cause a > ClassCastException during runtime). > > To show my question, take a look on the below aspect: > > aspect BC { > void around():execution(* C.*(..)) && args(List<Number>) {} // Matchs > C.m > void around():execution(* C.*(..)) && args(ArrayList<Number>) {} // DOES > NOT MATCH C.m > } > > This is exactly the same aspect I've shown before, just changing type > parameter from Integer to Number in both args(..) constructions. > Note that in BC aspect, the first advice follows the same semantics than the > AC one, and then, matches the method C.m. However, the second advice DOES > NOT follow the same semantics (that the AC one), and then, DOES NOT MATCH > C.m AT ALL. > > My question is: > Should not the second advice of BC aspect match the method C.m and use a > runtime check to verify if the given parameter is an ArrayList? Some one can > explain to me why the second advice is not matching the method C.m? > > The same problem is found in the following using the <? extends Number> > aspect CC { > void around():execution(* C.*(..)) && args(List<? extends Number>) {} > // Matchs C.m > void around():execution(* C.*(..)) && args(ArrayList<? extends Number>) > {} // DOES NOT MATCH C.m > } > > > There exists a formal description saying how args(..) and after(..) > returning (..) must works? > > > Thanks in advance > Fernando Rubbo > > _______________________________________________ > aspectj-users mailing list > aspectj-users@eclipse.org > https://dev.eclipse.org/mailman/listinfo/aspectj-users > > -- Eric Bodden Sable Research Group, McGill University, Montréal, Canada Got an interesting job offer? http://www.bodden.de/hire-me/ _______________________________________________ aspectj-users mailing list aspectj-users@eclipse.org https://dev.eclipse.org/mailman/listinfo/aspectj-users