1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
package language;
public class Initialization {
public static void main(String[] argList) {
Thing thing = new Thing();
if (12 != thing.counter) {
System.err.println("expected 12, got " + thing.counter);
}
thing = new Thing(20);
if (32 != thing.counter) {
System.err.println("expected 32, got " + thing.counter);
}
thing = new AnotherThing();
if (2 != thing.counter) {
System.err.println("expected 2, got " + thing.counter);
}
thing = new AnotherThing(20);
if (23 != thing.counter) {
System.err.println("expected 23, got " + thing.counter);
}
}
}
/** @author Erik Hilsdale, Wes Isberg */
// START-SAMPLE language-initialization Understanding object creation join points
/*
* To work with an object right when it is constructed,
* understand the differences between the join points for
* constructor call, constructor execution, and initialization.
*/
class Thing {
int counter;
Thing() {
this(1);
}
Thing(int value) {
counter = value;
}
}
class AnotherThing extends Thing {
AnotherThing() {
super();
}
AnotherThing(int i) {
super(++i);
}
}
aspect A {
/**
* After any call to any constructor, fix up the thing.
* In AspectJ 1.1, this only affects callers in the input
* classes or source files, but not super calls.
*/
after() returning (Thing thing):
call(Thing.new(..)) {
postInitialize(thing);
}
/**
* After executing the int constructor, fix up the thing.
* This works regardless of how the constructor was called
* (by outside code or by super), but only for the
* specified constructors.
*/
after() returning (Thing thing): execution(Thing.new(int)) {
thing.counter++;
}
/**
* DANGER -- BAD!! Before executing the int constructor,
* this uses the target object, which is not constructed.
*/
before (Thing thing): this(thing) && execution(Thing.new(int)) {
// thing.counter++; // DANGER!! thing not constructed yet.
}
/**
* This advises all Thing constructors in one join point,
* even if they call each other with this().
*/
after(Thing thing) returning: this(thing)
&& initialization(Thing.new(..)) {
thing.counter++;
}
protected void postInitialize(Thing thing) {
thing.counter += 10;
}
}
//END-SAMPLE language-initialization
|