Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Understanding generic types in args(..) construction

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

Back to the top