summaryrefslogtreecommitdiffstats
path: root/docs/sandbox/common/language/Initialization.java
blob: 46d3ec872998a3269e3a8cdd7aa25f380bddb2a9 (plain)
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