xref: /aosp_15_r20/external/javassist/tutorial/tutorial2.html (revision f1fbf3c2ab775ce834e0af96b7a85bdc7a0eac65)
1*f1fbf3c2SXin Li<html>
2*f1fbf3c2SXin Li<head>
3*f1fbf3c2SXin Li   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
4*f1fbf3c2SXin Li   <title>Javassist Tutorial</title>
5*f1fbf3c2SXin Li   <link rel="stylesheet" type="text/css" href="brown.css">
6*f1fbf3c2SXin Li</head>
7*f1fbf3c2SXin Li
8*f1fbf3c2SXin Li<body>
9*f1fbf3c2SXin Li
10*f1fbf3c2SXin Li<div align="right">Getting Started with Javassist</div>
11*f1fbf3c2SXin Li
12*f1fbf3c2SXin Li<div align="left"><a href="tutorial.html">Previous page</a></div>
13*f1fbf3c2SXin Li<div align="right"><a href="tutorial3.html">Next page</a></div>
14*f1fbf3c2SXin Li
15*f1fbf3c2SXin Li<p>
16*f1fbf3c2SXin Li<a href="#intro">4. Introspection and customization</a>
17*f1fbf3c2SXin Li<ul>
18*f1fbf3c2SXin Li<li><a href="#before">Inserting source text at the beginning/end of a method body</a>
19*f1fbf3c2SXin Li<br><li><a href="#alter">Altering a method body</a>
20*f1fbf3c2SXin Li<br><li><a href="#add">Adding a new method or field</a>
21*f1fbf3c2SXin Li<br><li><a href="#runtime">Runtime support classes</a>
22*f1fbf3c2SXin Li<br><li><a href="#annotation">Annotations</a>
23*f1fbf3c2SXin Li<br><li><a href="#import">Import</a>
24*f1fbf3c2SXin Li<br><li><a href="#limit">Limitations</a>
25*f1fbf3c2SXin Li</ul>
26*f1fbf3c2SXin Li
27*f1fbf3c2SXin Li<p><br>
28*f1fbf3c2SXin Li
29*f1fbf3c2SXin Li<a name="intro">
30*f1fbf3c2SXin Li<h2>4. Introspection and customization</h2>
31*f1fbf3c2SXin Li
32*f1fbf3c2SXin Li<p><code>CtClass</code> provides methods for introspection.  The
33*f1fbf3c2SXin Liintrospective ability of Javassist is compatible with that of
34*f1fbf3c2SXin Lithe Java reflection API.  <code>CtClass</code> provides
35*f1fbf3c2SXin Li<code>getName()</code>, <code>getSuperclass()</code>,
36*f1fbf3c2SXin Li<code>getMethods()</code>, and so on.
37*f1fbf3c2SXin Li<code>CtClass</code> also provides methods for modifying a class
38*f1fbf3c2SXin Lidefinition.  It allows to add a new field, constructor, and method.
39*f1fbf3c2SXin LiInstrumenting a method body is also possible.
40*f1fbf3c2SXin Li
41*f1fbf3c2SXin Li<p>
42*f1fbf3c2SXin LiMethods are represented by <code>CtMethod</code> objects.
43*f1fbf3c2SXin Li<code>CtMethod</code> provides several methods for modifying
44*f1fbf3c2SXin Lithe definition of the method.  Note that if a method is inherited
45*f1fbf3c2SXin Lifrom a super class, then
46*f1fbf3c2SXin Lithe same <code>CtMethod</code> object
47*f1fbf3c2SXin Lithat represents the inherited method represents the method declared
48*f1fbf3c2SXin Liin that super class.
49*f1fbf3c2SXin LiA <code>CtMethod</code> object corresponds to every method declaration.
50*f1fbf3c2SXin Li
51*f1fbf3c2SXin Li<p>
52*f1fbf3c2SXin LiFor example, if class <code>Point</code> declares method <code>move()</code>
53*f1fbf3c2SXin Liand a subclass <code>ColorPoint</code> of <code>Point</code> does
54*f1fbf3c2SXin Linot override <code>move()</code>, the two <code>move()</code> methods
55*f1fbf3c2SXin Lideclared in <code>Point</code> and inherited in <code>ColorPoint</code>
56*f1fbf3c2SXin Liare represented by the identical <code>CtMethod</code> object.
57*f1fbf3c2SXin LiIf the method definition represented by this
58*f1fbf3c2SXin Li<code>CtMethod</code> object is modified, the modification is
59*f1fbf3c2SXin Lireflected on both the methods.
60*f1fbf3c2SXin LiIf you want to modify only the <code>move()</code> method in
61*f1fbf3c2SXin Li<code>ColorPoint</code>, you first have to add to <code>ColorPoint</code>
62*f1fbf3c2SXin Lia copy of the <code>CtMethod</code> object representing <code>move()</code>
63*f1fbf3c2SXin Liin <code>Point</code>.  A copy of the the <code>CtMethod</code> object
64*f1fbf3c2SXin Lican be obtained by <code>CtNewMethod.copy()</code>.
65*f1fbf3c2SXin Li
66*f1fbf3c2SXin Li
67*f1fbf3c2SXin Li<p><hr width="40%">
68*f1fbf3c2SXin Li
69*f1fbf3c2SXin Li<ul>
70*f1fbf3c2SXin LiJavassist does not allow to remove a method or field, but it allows
71*f1fbf3c2SXin Lito change the name.  So if a method is not necessary any more, it should be
72*f1fbf3c2SXin Lirenamed and changed to be a private method by calling
73*f1fbf3c2SXin Li<code>setName()</code>
74*f1fbf3c2SXin Liand <code>setModifiers()</code> declared in <code>CtMethod</code>.
75*f1fbf3c2SXin Li
76*f1fbf3c2SXin Li<p>Javassist does not allow to add an extra parameter to an existing
77*f1fbf3c2SXin Limethod, either.  Instead of doing that, a new method receiving the
78*f1fbf3c2SXin Liextra parameter as well as the other parameters should be added to the
79*f1fbf3c2SXin Lisame class.  For example, if you want to add an extra <code>int</code>
80*f1fbf3c2SXin Liparameter <code>newZ</code> to a method:
81*f1fbf3c2SXin Li
82*f1fbf3c2SXin Li<ul><pre>void move(int newX, int newY) { x = newX; y = newY; }</pre></ul>
83*f1fbf3c2SXin Li
84*f1fbf3c2SXin Li<p>in a <code>Point</code> class, then you should add the following
85*f1fbf3c2SXin Limethod to the <code>Point</code> class:
86*f1fbf3c2SXin Li
87*f1fbf3c2SXin Li<ul><pre>void move(int newX, int newY, int newZ) {
88*f1fbf3c2SXin Li    // do what you want with newZ.
89*f1fbf3c2SXin Li    move(newX, newY);
90*f1fbf3c2SXin Li}</pre></ul>
91*f1fbf3c2SXin Li
92*f1fbf3c2SXin Li</ul>
93*f1fbf3c2SXin Li
94*f1fbf3c2SXin Li<p><hr width="40%">
95*f1fbf3c2SXin Li
96*f1fbf3c2SXin Li<p>Javassist also provides low-level API for directly editing a raw
97*f1fbf3c2SXin Liclass file.  For example, <code>getClassFile()</code> in
98*f1fbf3c2SXin Li<code>CtClass</code> returns a <code>ClassFile</code> object
99*f1fbf3c2SXin Lirepresenting a raw class file.  <code>getMethodInfo()</code> in
100*f1fbf3c2SXin Li<code>CtMethod</code> returns a <code>MethodInfo</code> object
101*f1fbf3c2SXin Lirepresenting a <code>method_info</code> structure included in a class
102*f1fbf3c2SXin Lifile.  The low-level API uses the vocabulary from the Java Virtual
103*f1fbf3c2SXin Limachine specification.  The users must have the knowledge about class
104*f1fbf3c2SXin Lifiles and bytecode.  For more details, the users should see the
105*f1fbf3c2SXin Li<a href="tutorial3.html#intro"><code>javassist.bytecode</code> package</a>.
106*f1fbf3c2SXin Li
107*f1fbf3c2SXin Li<p>The class files modified by Javassist requires the
108*f1fbf3c2SXin Li<code>javassist.runtime</code> package for runtime support
109*f1fbf3c2SXin Lionly if some special identifiers starting with <code>$</code>
110*f1fbf3c2SXin Liare used.  Those special identifiers are described below.
111*f1fbf3c2SXin LiThe class files modified without those special identifiers
112*f1fbf3c2SXin Lido not need the <code>javassist.runtime</code> package or any
113*f1fbf3c2SXin Liother Javassist packages at runtime.
114*f1fbf3c2SXin LiFor more details, see the API documentation
115*f1fbf3c2SXin Liof the <code>javassist.runtime</code> package.
116*f1fbf3c2SXin Li
117*f1fbf3c2SXin Li<p><br>
118*f1fbf3c2SXin Li
119*f1fbf3c2SXin Li<a name="before">
120*f1fbf3c2SXin Li<h3>4.1 Inserting source text at the beginning/end of a method body</h3>
121*f1fbf3c2SXin Li
122*f1fbf3c2SXin Li<p><code>CtMethod</code> and <code>CtConstructor</code> provide
123*f1fbf3c2SXin Limethods <code>insertBefore()</code>, <code>insertAfter()</code>, and
124*f1fbf3c2SXin Li<code>addCatch()</code>.  They are used for inserting a code fragment
125*f1fbf3c2SXin Liinto the body of an existing method.  The users can specify those code
126*f1fbf3c2SXin Lifragments with <em>source text</em> written in Java.
127*f1fbf3c2SXin LiJavassist includes a simple Java compiler for processing source
128*f1fbf3c2SXin Litext.  It receives source text
129*f1fbf3c2SXin Liwritten in Java and compiles it into Java bytecode, which will be
130*f1fbf3c2SXin Li<em>inlined</em> into a method body.
131*f1fbf3c2SXin Li
132*f1fbf3c2SXin Li<p>
133*f1fbf3c2SXin LiInserting a code fragment at the position specified by a line number
134*f1fbf3c2SXin Liis also possible
135*f1fbf3c2SXin Li(if the line number table is contained in the class file).
136*f1fbf3c2SXin Li<code>insertAt()</code> in <code>CtMethod</code> and
137*f1fbf3c2SXin Li<code>CtConstructor</code> takes source text and a line number in the source
138*f1fbf3c2SXin Lifile of the original class definition.
139*f1fbf3c2SXin LiIt compiles the source text and inserts the compiled code at the line number.
140*f1fbf3c2SXin Li
141*f1fbf3c2SXin Li<p>The methods <code>insertBefore()</code>, <code>insertAfter()</code>,
142*f1fbf3c2SXin Li<code>addCatch()</code>, and <code>insertAt()</code>
143*f1fbf3c2SXin Lireceive a <code>String</code> object representing
144*f1fbf3c2SXin Lia statement or a block.  A statement is a single control structure like
145*f1fbf3c2SXin Li<code>if</code> and <code>while</code> or an expression ending with
146*f1fbf3c2SXin Lia semi colon (<code>;</code>).  A block is a set of
147*f1fbf3c2SXin Listatements surrounded with braces <code>{}</code>.
148*f1fbf3c2SXin LiHence each of the following lines is an example of valid statement or block:
149*f1fbf3c2SXin Li
150*f1fbf3c2SXin Li<ul><pre>System.out.println("Hello");
151*f1fbf3c2SXin Li{ System.out.println("Hello"); }
152*f1fbf3c2SXin Liif (i < 0) { i = -i; }
153*f1fbf3c2SXin Li</pre></ul>
154*f1fbf3c2SXin Li
155*f1fbf3c2SXin Li<p>The statement and the block can refer to fields and methods.
156*f1fbf3c2SXin LiThey can also refer to the parameters
157*f1fbf3c2SXin Lito the method that they are inserted into
158*f1fbf3c2SXin Liif that method was compiled with the -g option
159*f1fbf3c2SXin Li(to include a local variable attribute in the class file).
160*f1fbf3c2SXin LiOtherwise, they must access the method parameters through the special
161*f1fbf3c2SXin Livariables <code>$0</code>, <code>$1</code>, <code>$2</code>, ... described
162*f1fbf3c2SXin Libelow.
163*f1fbf3c2SXin Li<em>Accessing local variables declared in the method is not allowed</em>
164*f1fbf3c2SXin Lialthough declaring a new local variable in the block is allowed.
165*f1fbf3c2SXin LiHowever, <code>insertAt()</code> allows the statement and the block
166*f1fbf3c2SXin Lito access local variables
167*f1fbf3c2SXin Liif these variables are available at the specified line number
168*f1fbf3c2SXin Liand the target method was compiled with the -g option.
169*f1fbf3c2SXin Li
170*f1fbf3c2SXin Li
171*f1fbf3c2SXin Li<!--
172*f1fbf3c2SXin Li<p><center><table border=8 cellspacing=0 bordercolor="#cfcfcf">
173*f1fbf3c2SXin Li<tr><td bgcolor="#cfcfcf">
174*f1fbf3c2SXin Li<b>Tip:</b>
175*f1fbf3c2SXin Li<br>&nbsp&nbsp&nbsp Local variables are not accessible.&nbsp&nbsp
176*f1fbf3c2SXin Li</td></tr>
177*f1fbf3c2SXin Li</table></center>
178*f1fbf3c2SXin Li-->
179*f1fbf3c2SXin Li
180*f1fbf3c2SXin Li<p>The <code>String</code> object passed to the methods
181*f1fbf3c2SXin Li<code>insertBefore()</code>, <code>insertAfter()</code>,
182*f1fbf3c2SXin Li<code>addCatch()</code>, and <code>insertAt()</code> are compiled by
183*f1fbf3c2SXin Lithe compiler included in Javassist.
184*f1fbf3c2SXin LiSince the compiler supports language extensions,
185*f1fbf3c2SXin Liseveral identifiers starting with <code>$</code>
186*f1fbf3c2SXin Lihave special meaning:
187*f1fbf3c2SXin Li
188*f1fbf3c2SXin Li<ul><table border=0>
189*f1fbf3c2SXin Li<tr>
190*f1fbf3c2SXin Li<td><code>$0</code>, <code>$1</code>, <code>$2</code>, ... &nbsp &nbsp</td>
191*f1fbf3c2SXin Li<td><code>this</code> and actual parameters</td>
192*f1fbf3c2SXin Li</tr>
193*f1fbf3c2SXin Li
194*f1fbf3c2SXin Li<tr>
195*f1fbf3c2SXin Li<td><code>$args</code></td>
196*f1fbf3c2SXin Li<td>An array of parameters.
197*f1fbf3c2SXin LiThe type of <code>$args</code> is <code>Object[]</code>.
198*f1fbf3c2SXin Li</td>
199*f1fbf3c2SXin Li</tr>
200*f1fbf3c2SXin Li
201*f1fbf3c2SXin Li<tr>
202*f1fbf3c2SXin Li<td><code>$$</code></td>
203*f1fbf3c2SXin Li<td rowspan=2>All actual parameters.<br>
204*f1fbf3c2SXin LiFor example, <code>m($$)</code> is equivalent to
205*f1fbf3c2SXin Li<code>m($1,$2,</code>...<code>)</code></td>
206*f1fbf3c2SXin Li</tr>
207*f1fbf3c2SXin Li
208*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
209*f1fbf3c2SXin Li
210*f1fbf3c2SXin Li<tr>
211*f1fbf3c2SXin Li<td><code>$cflow(</code>...<code>)</code></td>
212*f1fbf3c2SXin Li<td><code>cflow</code> variable</td>
213*f1fbf3c2SXin Li</tr>
214*f1fbf3c2SXin Li
215*f1fbf3c2SXin Li<tr>
216*f1fbf3c2SXin Li<td><code>$r</code></td>
217*f1fbf3c2SXin Li<td>The result type.  It is used in a cast expression.</td>
218*f1fbf3c2SXin Li</tr>
219*f1fbf3c2SXin Li
220*f1fbf3c2SXin Li<tr>
221*f1fbf3c2SXin Li<td><code>$w</code></td>
222*f1fbf3c2SXin Li<td>The wrapper type.  It is used in a cast expression.</td>
223*f1fbf3c2SXin Li</tr>
224*f1fbf3c2SXin Li
225*f1fbf3c2SXin Li<tr>
226*f1fbf3c2SXin Li<td><code>$_</code></td>
227*f1fbf3c2SXin Li<td>The resulting value</td>
228*f1fbf3c2SXin Li</tr>
229*f1fbf3c2SXin Li
230*f1fbf3c2SXin Li<tr>
231*f1fbf3c2SXin Li<td><code>$sig</code></td>
232*f1fbf3c2SXin Li<td>An array of <code>java.lang.Class</code> objects representing
233*f1fbf3c2SXin Lithe formal parameter types.
234*f1fbf3c2SXin Li</td>
235*f1fbf3c2SXin Li</tr>
236*f1fbf3c2SXin Li
237*f1fbf3c2SXin Li<tr>
238*f1fbf3c2SXin Li<td><code>$type</code></td>
239*f1fbf3c2SXin Li<td>A <code>java.lang.Class</code> object representing
240*f1fbf3c2SXin Lithe formal result type.</td>
241*f1fbf3c2SXin Li</tr>
242*f1fbf3c2SXin Li
243*f1fbf3c2SXin Li<tr>
244*f1fbf3c2SXin Li<td><code>$class</code></td>
245*f1fbf3c2SXin Li<td>A <code>java.lang.Class</code> object representing
246*f1fbf3c2SXin Lithe class currently edited.</td>
247*f1fbf3c2SXin Li</tr>
248*f1fbf3c2SXin Li
249*f1fbf3c2SXin Li</table>
250*f1fbf3c2SXin Li</ul>
251*f1fbf3c2SXin Li
252*f1fbf3c2SXin Li<h4>$0, $1, $2, ...</h4>
253*f1fbf3c2SXin Li
254*f1fbf3c2SXin Li<p>The parameters passed to the target method
255*f1fbf3c2SXin Liare accessible with
256*f1fbf3c2SXin Li<code>$1</code>, <code>$2</code>, ... instead of
257*f1fbf3c2SXin Lithe original parameter names.
258*f1fbf3c2SXin Li<code>$1</code> represents the
259*f1fbf3c2SXin Lifirst parameter, <code>$2</code> represents the second parameter, and
260*f1fbf3c2SXin Liso on.  The types of those variables are identical to the parameter
261*f1fbf3c2SXin Litypes.
262*f1fbf3c2SXin Li<code>$0</code> is
263*f1fbf3c2SXin Liequivalent to <code>this</code>.  If the method is static,
264*f1fbf3c2SXin Li<code>$0</code> is not available.
265*f1fbf3c2SXin Li
266*f1fbf3c2SXin Li<p>These variables are used as following.  Suppose that a class
267*f1fbf3c2SXin Li<code>Point</code>:
268*f1fbf3c2SXin Li
269*f1fbf3c2SXin Li<pre><ul>class Point {
270*f1fbf3c2SXin Li    int x, y;
271*f1fbf3c2SXin Li    void move(int dx, int dy) { x += dx; y += dy; }
272*f1fbf3c2SXin Li}
273*f1fbf3c2SXin Li</ul></pre>
274*f1fbf3c2SXin Li
275*f1fbf3c2SXin Li<p>To print the values of <code>dx</code> and <code>dy</code>
276*f1fbf3c2SXin Liwhenever the method <code>move()</code> is called, execute this
277*f1fbf3c2SXin Liprogram:
278*f1fbf3c2SXin Li
279*f1fbf3c2SXin Li<ul><pre>ClassPool pool = ClassPool.getDefault();
280*f1fbf3c2SXin LiCtClass cc = pool.get("Point");
281*f1fbf3c2SXin LiCtMethod m = cc.getDeclaredMethod("move");
282*f1fbf3c2SXin Lim.insertBefore("{ System.out.println($1); System.out.println($2); }");
283*f1fbf3c2SXin Licc.writeFile();
284*f1fbf3c2SXin Li</pre></ul>
285*f1fbf3c2SXin Li
286*f1fbf3c2SXin Li<p>Note that the source text passed to <code>insertBefore()</code> is
287*f1fbf3c2SXin Lisurrounded with braces <code>{}</code>.
288*f1fbf3c2SXin Li<code>insertBefore()</code> accepts only a single statement or a block
289*f1fbf3c2SXin Lisurrounded with braces.
290*f1fbf3c2SXin Li
291*f1fbf3c2SXin Li<p>The definition of the class <code>Point</code> after the
292*f1fbf3c2SXin Limodification is like this:
293*f1fbf3c2SXin Li
294*f1fbf3c2SXin Li<pre><ul>class Point {
295*f1fbf3c2SXin Li    int x, y;
296*f1fbf3c2SXin Li    void move(int dx, int dy) {
297*f1fbf3c2SXin Li        { System.out.println(dx); System.out.println(dy); }
298*f1fbf3c2SXin Li        x += dx; y += dy;
299*f1fbf3c2SXin Li    }
300*f1fbf3c2SXin Li}
301*f1fbf3c2SXin Li</ul></pre>
302*f1fbf3c2SXin Li
303*f1fbf3c2SXin Li<p><code>$1</code> and <code>$2</code> are replaced with
304*f1fbf3c2SXin Li<code>dx</code> and <code>dy</code>, respectively.
305*f1fbf3c2SXin Li
306*f1fbf3c2SXin Li<p><code>$1</code>, <code>$2</code>, <code>$3</code> ... are
307*f1fbf3c2SXin Liupdatable.  If a new value is assigend to one of those variables,
308*f1fbf3c2SXin Lithen the value of the parameter represented by that variable is
309*f1fbf3c2SXin Lialso updated.
310*f1fbf3c2SXin Li
311*f1fbf3c2SXin Li
312*f1fbf3c2SXin Li<h4>$args</h4>
313*f1fbf3c2SXin Li
314*f1fbf3c2SXin Li<p>The variable <code>$args</code> represents an array of all the
315*f1fbf3c2SXin Liparameters.  The type of that variable is an array of class
316*f1fbf3c2SXin Li<code>Object</code>.  If a parameter type is a primitive type such as
317*f1fbf3c2SXin Li<code>int</code>, then the parameter value is converted into a wrapper
318*f1fbf3c2SXin Liobject such as <code>java.lang.Integer</code> to store in
319*f1fbf3c2SXin Li<code>$args</code>.  Thus, <code>$args[0]</code> is equivalent to
320*f1fbf3c2SXin Li<code>$1</code> unless the type of the first parameter is a primitive
321*f1fbf3c2SXin Litype.  Note that <code>$args[0]</code> is not equivalent to
322*f1fbf3c2SXin Li<code>$0</code>; <code>$0</code> represents <code>this</code>.
323*f1fbf3c2SXin Li
324*f1fbf3c2SXin Li<p>If an array of <code>Object</code> is assigned to
325*f1fbf3c2SXin Li<code>$args</code>, then each element of that array is
326*f1fbf3c2SXin Liassigned to each parameter.  If a parameter type is a primitive
327*f1fbf3c2SXin Litype, the type of the corresponding element must be a wrapper type.
328*f1fbf3c2SXin LiThe value is converted from the wrapper type to the primitive type
329*f1fbf3c2SXin Libefore it is assigned to the parameter.
330*f1fbf3c2SXin Li
331*f1fbf3c2SXin Li<h4>$$</h4>
332*f1fbf3c2SXin Li
333*f1fbf3c2SXin Li<p>The variable <code>$$</code> is abbreviation of a list of
334*f1fbf3c2SXin Liall the parameters separated by commas.
335*f1fbf3c2SXin LiFor example, if the number of the parameters
336*f1fbf3c2SXin Lito method <code>move()</code> is three, then
337*f1fbf3c2SXin Li
338*f1fbf3c2SXin Li<ul><pre>move($$)</pre></ul>
339*f1fbf3c2SXin Li
340*f1fbf3c2SXin Li<p>is equivalent to this:
341*f1fbf3c2SXin Li
342*f1fbf3c2SXin Li<ul><pre>move($1, $2, $3)</pre></ul>
343*f1fbf3c2SXin Li
344*f1fbf3c2SXin Li<p>If <code>move()</code> does not take any parameters,
345*f1fbf3c2SXin Lithen <code>move($$)</code> is
346*f1fbf3c2SXin Liequivalent to <code>move()</code>.
347*f1fbf3c2SXin Li
348*f1fbf3c2SXin Li<p><code>$$</code> can be used with another method.
349*f1fbf3c2SXin LiIf you write an expression:
350*f1fbf3c2SXin Li
351*f1fbf3c2SXin Li<ul><pre>exMove($$, context)</pre></ul>
352*f1fbf3c2SXin Li
353*f1fbf3c2SXin Li<p>then this expression is equivalent to:
354*f1fbf3c2SXin Li
355*f1fbf3c2SXin Li<ul><pre>exMove($1, $2, $3, context)</pre></ul>
356*f1fbf3c2SXin Li
357*f1fbf3c2SXin Li<p>Note that <code>$$</code> enables generic notation of method call
358*f1fbf3c2SXin Liwith respect to the number of parameters.
359*f1fbf3c2SXin LiIt is typically used with <code>$proceed</code> shown later.
360*f1fbf3c2SXin Li
361*f1fbf3c2SXin Li<h4>$cflow</h4>
362*f1fbf3c2SXin Li
363*f1fbf3c2SXin Li<p><code>$cflow</code> means "control flow".
364*f1fbf3c2SXin LiThis read-only variable returns the depth of the recursive calls
365*f1fbf3c2SXin Lito a specific method.
366*f1fbf3c2SXin Li
367*f1fbf3c2SXin Li<p>Suppose that the method shown below is represented by a
368*f1fbf3c2SXin Li<code>CtMethod</code> object <code>cm</code>:
369*f1fbf3c2SXin Li
370*f1fbf3c2SXin Li<ul><pre>int fact(int n) {
371*f1fbf3c2SXin Li    if (n <= 1)
372*f1fbf3c2SXin Li        return n;
373*f1fbf3c2SXin Li    else
374*f1fbf3c2SXin Li        return n * fact(n - 1);
375*f1fbf3c2SXin Li}</pre></ul>
376*f1fbf3c2SXin Li
377*f1fbf3c2SXin Li<p>To use <code>$cflow</code>, first declare that <code>$cflow</code>
378*f1fbf3c2SXin Liis used for monitoring calls to the method <code>fact()</code>:
379*f1fbf3c2SXin Li
380*f1fbf3c2SXin Li<ul><pre>CtMethod cm = ...;
381*f1fbf3c2SXin Licm.useCflow("fact");</pre></ul>
382*f1fbf3c2SXin Li
383*f1fbf3c2SXin Li<p>The parameter to <code>useCflow()</code> is the identifier of the
384*f1fbf3c2SXin Lideclared <code>$cflow</code> variable.  Any valid Java name can be
385*f1fbf3c2SXin Liused as the identifier.  Since the identifier can also include
386*f1fbf3c2SXin Li<code>.</code> (dot), for example, <code>"my.Test.fact"</code>
387*f1fbf3c2SXin Liis a valid identifier.
388*f1fbf3c2SXin Li
389*f1fbf3c2SXin Li<p>Then, <code>$cflow(fact)</code> represents the depth of the
390*f1fbf3c2SXin Lirecursive calls to the method specified by <code>cm</code>.  The value
391*f1fbf3c2SXin Liof <code>$cflow(fact)</code> is 0 (zero) when the method is
392*f1fbf3c2SXin Lifirst called whereas it is 1 when the method is recursively called
393*f1fbf3c2SXin Liwithin the method.  For example,
394*f1fbf3c2SXin Li
395*f1fbf3c2SXin Li<ul><pre>
396*f1fbf3c2SXin Licm.insertBefore("if ($cflow(fact) == 0)"
397*f1fbf3c2SXin Li              + "    System.out.println(\"fact \" + $1);");
398*f1fbf3c2SXin Li</pre></ul>
399*f1fbf3c2SXin Li
400*f1fbf3c2SXin Li<p>translates the method <code>fact()</code> so that it shows the
401*f1fbf3c2SXin Liparameter.  Since the value of <code>$cflow(fact)</code> is checked,
402*f1fbf3c2SXin Lithe method <code>fact()</code> does not show the parameter if it is
403*f1fbf3c2SXin Lirecursively called within <code>fact()</code>.
404*f1fbf3c2SXin Li
405*f1fbf3c2SXin Li<p>The value of <code>$cflow</code> is the number of stack frames
406*f1fbf3c2SXin Liassociated with the specified method <code>cm</code>
407*f1fbf3c2SXin Liunder the current topmost
408*f1fbf3c2SXin Listack frame for the current thread.  <code>$cflow</code> is also
409*f1fbf3c2SXin Liaccessible within a method different from the specified method
410*f1fbf3c2SXin Li<code>cm</code>.
411*f1fbf3c2SXin Li
412*f1fbf3c2SXin Li<h4>$r</h4>
413*f1fbf3c2SXin Li
414*f1fbf3c2SXin Li<p><code>$r</code> represents the result type (return type) of the method.
415*f1fbf3c2SXin LiIt must be used as the cast type in a cast expression.
416*f1fbf3c2SXin LiFor example, this is a typical use:
417*f1fbf3c2SXin Li
418*f1fbf3c2SXin Li<ul><pre>Object result = ... ;
419*f1fbf3c2SXin Li$_ = ($r)result;</pre></ul>
420*f1fbf3c2SXin Li
421*f1fbf3c2SXin Li<p>If the result type is a primitive type, then <code>($r)</code>
422*f1fbf3c2SXin Lifollows special semantics.  First, if the operand type of the cast
423*f1fbf3c2SXin Liexpression is a primitive type, <code>($r)</code> works as a normal
424*f1fbf3c2SXin Licast operator to the result type.
425*f1fbf3c2SXin LiOn the other hand, if the operand type is a wrapper type,
426*f1fbf3c2SXin Li<code>($r)</code> converts from the wrapper type to the result type.
427*f1fbf3c2SXin LiFor example, if the result type is <code>int</code>, then
428*f1fbf3c2SXin Li<code>($r)</code> converts from <code>java.lang.Integer</code> to
429*f1fbf3c2SXin Li<code>int</code>.
430*f1fbf3c2SXin Li
431*f1fbf3c2SXin Li<p>If the result type is <code>void</code>, then
432*f1fbf3c2SXin Li<code>($r)</code> does not convert a type; it does nothing.
433*f1fbf3c2SXin LiHowever, if the operand is a call to a <code>void</code> method,
434*f1fbf3c2SXin Lithen <code>($r)</code> results in <code>null</code>.  For example,
435*f1fbf3c2SXin Liif the result type is <code>void</code> and
436*f1fbf3c2SXin Li<code>foo()</code> is a <code>void</code> method, then
437*f1fbf3c2SXin Li
438*f1fbf3c2SXin Li<ul><pre>$_ = ($r)foo();</pre></ul>
439*f1fbf3c2SXin Li
440*f1fbf3c2SXin Li<p>is a valid statement.
441*f1fbf3c2SXin Li
442*f1fbf3c2SXin Li<p>The cast operator <code>($r)</code> is also useful in a
443*f1fbf3c2SXin Li<code>return</code> statement.  Even if the result type is
444*f1fbf3c2SXin Li<code>void</code>, the following <code>return</code> statement is valid:
445*f1fbf3c2SXin Li
446*f1fbf3c2SXin Li<ul><pre>return ($r)result;</pre></ul>
447*f1fbf3c2SXin Li
448*f1fbf3c2SXin Li<p>Here, <code>result</code> is some local variable.
449*f1fbf3c2SXin LiSince <code>($r)</code> is specified, the resulting value is
450*f1fbf3c2SXin Lidiscarded.
451*f1fbf3c2SXin LiThis <code>return</code> statement is regarded as the equivalent
452*f1fbf3c2SXin Liof the <code>return</code> statement without a resulting value:
453*f1fbf3c2SXin Li
454*f1fbf3c2SXin Li<ul><pre>return;</pre></ul>
455*f1fbf3c2SXin Li
456*f1fbf3c2SXin Li<h4>$w</h4>
457*f1fbf3c2SXin Li
458*f1fbf3c2SXin Li<p><code>$w</code> represents a wrapper type.
459*f1fbf3c2SXin LiIt must be used as the cast type in a cast expression.
460*f1fbf3c2SXin Li<code>($w)</code> converts from a primitive type to the corresponding
461*f1fbf3c2SXin Liwrapper type.
462*f1fbf3c2SXin Li
463*f1fbf3c2SXin LiThe following code is an example:
464*f1fbf3c2SXin Li
465*f1fbf3c2SXin Li<ul><pre>Integer i = ($w)5;</pre></ul>
466*f1fbf3c2SXin Li
467*f1fbf3c2SXin Li<p>The selected wrapper type depends on the type of the expression
468*f1fbf3c2SXin Lifollowing <code>($w)</code>.  If the type of the expression is
469*f1fbf3c2SXin Li<code>double</code>, then the wrapper type is <code>java.lang.Double</code>.
470*f1fbf3c2SXin Li
471*f1fbf3c2SXin Li<p>If the type of the expression following <code>($w)</code> is not
472*f1fbf3c2SXin Lia primitive type, then <code>($w)</code> does nothing.
473*f1fbf3c2SXin Li
474*f1fbf3c2SXin Li<h4>$_</h4>
475*f1fbf3c2SXin Li
476*f1fbf3c2SXin Li<p><code>insertAfter()</code> in <code>CtMethod</code> and
477*f1fbf3c2SXin Li<code>CtConstructor</code> inserts the
478*f1fbf3c2SXin Licompiled code at the end of the method.  In the statement given to
479*f1fbf3c2SXin Li<code>insertAfter()</code>, not only the variables shown above such as
480*f1fbf3c2SXin Li<code>$0</code>, <code>$1</code>, ... but also <code>$_</code> is
481*f1fbf3c2SXin Liavailable.
482*f1fbf3c2SXin Li
483*f1fbf3c2SXin Li<p>The variable <code>$_</code> represents the resulting value of the
484*f1fbf3c2SXin Limethod.
485*f1fbf3c2SXin LiThe type of that variable is the type of the result type (the
486*f1fbf3c2SXin Lireturn type) of the method.  If the result type is <code>void</code>,
487*f1fbf3c2SXin Lithen the type of <code>$_</code> is <code>Object</code> and the value
488*f1fbf3c2SXin Liof <code>$_</code> is <code>null</code>.
489*f1fbf3c2SXin Li
490*f1fbf3c2SXin Li<p>Although the compiled code inserted by <code>insertAfter()</code>
491*f1fbf3c2SXin Liis executed just before the control normally returns from the method,
492*f1fbf3c2SXin Liit can be also executed when an exception is thrown from the method.
493*f1fbf3c2SXin LiTo execute it when an exception is thrown, the second parameter
494*f1fbf3c2SXin Li<code>asFinally</code> to <code>insertAfter()</code> must be
495*f1fbf3c2SXin Li<code>true</code>.
496*f1fbf3c2SXin Li
497*f1fbf3c2SXin Li<p>If an exception is thrown, the compiled code inserted by
498*f1fbf3c2SXin Li<code>insertAfter()</code> is executed as a <code>finally</code>
499*f1fbf3c2SXin Liclause.  The value of <code>$_</code> is <code>0</code> or
500*f1fbf3c2SXin Li<code>null</code> in the compiled code.  After the execution of the
501*f1fbf3c2SXin Licompiled code terminates, the exception originally thrown is re-thrown
502*f1fbf3c2SXin Lito the caller.  Note that the value of <code>$_</code> is never thrown
503*f1fbf3c2SXin Lito the caller; it is rather discarded.
504*f1fbf3c2SXin Li
505*f1fbf3c2SXin Li<h4>$sig</h4>
506*f1fbf3c2SXin Li
507*f1fbf3c2SXin Li<p>The value of <code>$sig</code> is an array of
508*f1fbf3c2SXin Li<code>java.lang.Class</code> objects that represent the formal
509*f1fbf3c2SXin Liparameter types in declaration order.
510*f1fbf3c2SXin Li
511*f1fbf3c2SXin Li<h4>$type</h4>
512*f1fbf3c2SXin Li
513*f1fbf3c2SXin Li<p>The value of <code>$type</code> is an <code>java.lang.Class</code>
514*f1fbf3c2SXin Liobject representing the formal type of the result value.  This
515*f1fbf3c2SXin Livariable refers to <code>Void.class</code> if this is a constructor.
516*f1fbf3c2SXin Li
517*f1fbf3c2SXin Li<h4>$class</h4>
518*f1fbf3c2SXin Li
519*f1fbf3c2SXin Li<p>The value of <code>$class</code> is an <code>java.lang.Class</code>
520*f1fbf3c2SXin Liobject representing the class in which the edited method is declared.
521*f1fbf3c2SXin LiThis represents the type of <code>$0</code>.
522*f1fbf3c2SXin Li
523*f1fbf3c2SXin Li<h4>addCatch()</h4>
524*f1fbf3c2SXin Li
525*f1fbf3c2SXin Li<p><code>addCatch()</code> inserts a code fragment into a method body
526*f1fbf3c2SXin Liso that the code fragment is executed when the method body throws
527*f1fbf3c2SXin Lian exception and the control returns to the caller.  In the source
528*f1fbf3c2SXin Litext representing the inserted code fragment, the exception value
529*f1fbf3c2SXin Liis referred to with the special variable <code>$e</code>.
530*f1fbf3c2SXin Li
531*f1fbf3c2SXin Li<p>For example, this program:
532*f1fbf3c2SXin Li
533*f1fbf3c2SXin Li<ul><pre>
534*f1fbf3c2SXin LiCtMethod m = ...;
535*f1fbf3c2SXin LiCtClass etype = ClassPool.getDefault().get("java.io.IOException");
536*f1fbf3c2SXin Lim.addCatch("{ System.out.println($e); throw $e; }", etype);
537*f1fbf3c2SXin Li</pre></ul>
538*f1fbf3c2SXin Li
539*f1fbf3c2SXin Li<p>translates the method body represented by <code>m</code> into
540*f1fbf3c2SXin Lisomething like this:
541*f1fbf3c2SXin Li
542*f1fbf3c2SXin Li<ul><pre>
543*f1fbf3c2SXin Litry {
544*f1fbf3c2SXin Li    <font face="serif"><em>the original method body</em></font>
545*f1fbf3c2SXin Li}
546*f1fbf3c2SXin Licatch (java.io.IOException e) {
547*f1fbf3c2SXin Li    System.out.println(e);
548*f1fbf3c2SXin Li    throw e;
549*f1fbf3c2SXin Li}
550*f1fbf3c2SXin Li</pre></ul>
551*f1fbf3c2SXin Li
552*f1fbf3c2SXin Li<p>Note that the inserted code fragment must end with a
553*f1fbf3c2SXin Li<code>throw</code> or <code>return</code> statement.
554*f1fbf3c2SXin Li
555*f1fbf3c2SXin Li<p><br>
556*f1fbf3c2SXin Li
557*f1fbf3c2SXin Li<a name="alter">
558*f1fbf3c2SXin Li<h3>4.2 Altering a method body</h3>
559*f1fbf3c2SXin Li
560*f1fbf3c2SXin Li<p><code>CtMethod</code> and <code>CtConstructor</code> provide
561*f1fbf3c2SXin Li<code>setBody()</code> for substituting a whole
562*f1fbf3c2SXin Limethod body.  They compile the given source text into Java bytecode
563*f1fbf3c2SXin Liand substitutes it for the original method body.  If the given source
564*f1fbf3c2SXin Litext is <code>null</code>, the substituted body includes only a
565*f1fbf3c2SXin Li<code>return</code> statement, which returns zero or null unless the
566*f1fbf3c2SXin Liresult type is <code>void</code>.
567*f1fbf3c2SXin Li
568*f1fbf3c2SXin Li<p>In the source text given to <code>setBody()</code>, the identifiers
569*f1fbf3c2SXin Listarting with <code>$</code> have special meaning
570*f1fbf3c2SXin Li
571*f1fbf3c2SXin Li<ul><table border=0>
572*f1fbf3c2SXin Li<tr>
573*f1fbf3c2SXin Li<td><code>$0</code>, <code>$1</code>, <code>$2</code>, ... &nbsp &nbsp</td>
574*f1fbf3c2SXin Li<td><code>this</code> and actual parameters</td>
575*f1fbf3c2SXin Li</tr>
576*f1fbf3c2SXin Li
577*f1fbf3c2SXin Li<tr>
578*f1fbf3c2SXin Li<td><code>$args</code></td>
579*f1fbf3c2SXin Li<td>An array of parameters.
580*f1fbf3c2SXin LiThe type of <code>$args</code> is <code>Object[]</code>.
581*f1fbf3c2SXin Li</td>
582*f1fbf3c2SXin Li</tr>
583*f1fbf3c2SXin Li
584*f1fbf3c2SXin Li<tr>
585*f1fbf3c2SXin Li<td><code>$$</code></td>
586*f1fbf3c2SXin Li<td>All actual parameters.<br>
587*f1fbf3c2SXin Li</tr>
588*f1fbf3c2SXin Li
589*f1fbf3c2SXin Li<tr>
590*f1fbf3c2SXin Li<td><code>$cflow(</code>...<code>)</code></td>
591*f1fbf3c2SXin Li<td><code>cflow</code> variable</td>
592*f1fbf3c2SXin Li</tr>
593*f1fbf3c2SXin Li
594*f1fbf3c2SXin Li<tr>
595*f1fbf3c2SXin Li<td><code>$r</code></td>
596*f1fbf3c2SXin Li<td>The result type.  It is used in a cast expression.</td>
597*f1fbf3c2SXin Li</tr>
598*f1fbf3c2SXin Li
599*f1fbf3c2SXin Li<tr>
600*f1fbf3c2SXin Li<td><code>$w</code></td>
601*f1fbf3c2SXin Li<td>The wrapper type.  It is used in a cast expression.</td>
602*f1fbf3c2SXin Li</tr>
603*f1fbf3c2SXin Li
604*f1fbf3c2SXin Li<tr>
605*f1fbf3c2SXin Li<td><code>$sig</code></td>
606*f1fbf3c2SXin Li<td>An array of <code>java.lang.Class</code> objects representing
607*f1fbf3c2SXin Lithe formal parameter types.
608*f1fbf3c2SXin Li</td>
609*f1fbf3c2SXin Li</tr>
610*f1fbf3c2SXin Li
611*f1fbf3c2SXin Li<tr>
612*f1fbf3c2SXin Li<td><code>$type</code></td>
613*f1fbf3c2SXin Li<td>A <code>java.lang.Class</code> object representing
614*f1fbf3c2SXin Lithe formal result type.</td>
615*f1fbf3c2SXin Li</tr>
616*f1fbf3c2SXin Li
617*f1fbf3c2SXin Li<tr>
618*f1fbf3c2SXin Li<td><code>$class</code></td>
619*f1fbf3c2SXin Li<td rowspan=2>A <code>java.lang.Class</code> object representing
620*f1fbf3c2SXin Lithe class that declares the method<br>
621*f1fbf3c2SXin Licurrently edited (the type of $0).</td>
622*f1fbf3c2SXin Li</tr>
623*f1fbf3c2SXin Li
624*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
625*f1fbf3c2SXin Li
626*f1fbf3c2SXin Li</table>
627*f1fbf3c2SXin Li</ul>
628*f1fbf3c2SXin Li
629*f1fbf3c2SXin LiNote that <code>$_</code> is not available.
630*f1fbf3c2SXin Li
631*f1fbf3c2SXin Li<h4>Substituting source text for an existing expression</h4>
632*f1fbf3c2SXin Li
633*f1fbf3c2SXin Li<p>Javassist allows modifying only an expression included in a method body.
634*f1fbf3c2SXin Li<code>javassist.expr.ExprEditor</code> is a class
635*f1fbf3c2SXin Lifor replacing an expression in a method body.
636*f1fbf3c2SXin LiThe users can define a subclass of <code>ExprEditor</code>
637*f1fbf3c2SXin Lito specify how an expression is modified.
638*f1fbf3c2SXin Li
639*f1fbf3c2SXin Li<p>To run an <code>ExprEditor</code> object, the users must
640*f1fbf3c2SXin Licall <code>instrument()</code> in <code>CtMethod</code> or
641*f1fbf3c2SXin Li<code>CtClass</code>.
642*f1fbf3c2SXin Li
643*f1fbf3c2SXin LiFor example,
644*f1fbf3c2SXin Li
645*f1fbf3c2SXin Li<ul><pre>
646*f1fbf3c2SXin LiCtMethod cm = ... ;
647*f1fbf3c2SXin Licm.instrument(
648*f1fbf3c2SXin Li    new ExprEditor() {
649*f1fbf3c2SXin Li        public void edit(MethodCall m)
650*f1fbf3c2SXin Li                      throws CannotCompileException
651*f1fbf3c2SXin Li        {
652*f1fbf3c2SXin Li            if (m.getClassName().equals("Point")
653*f1fbf3c2SXin Li                          && m.getMethodName().equals("move"))
654*f1fbf3c2SXin Li                m.replace("{ $1 = 0; $_ = $proceed($$); }");
655*f1fbf3c2SXin Li        }
656*f1fbf3c2SXin Li    });
657*f1fbf3c2SXin Li</pre></ul>
658*f1fbf3c2SXin Li
659*f1fbf3c2SXin Li<p>searches the method body represented by <code>cm</code> and
660*f1fbf3c2SXin Lireplaces all calls to <code>move()</code> in class <code>Point</code>
661*f1fbf3c2SXin Liwith a block:
662*f1fbf3c2SXin Li
663*f1fbf3c2SXin Li<ul><pre>{ $1 = 0; $_ = $proceed($$); }
664*f1fbf3c2SXin Li</pre></ul>
665*f1fbf3c2SXin Li
666*f1fbf3c2SXin Li<p>so that the first parameter to <code>move()</code> is always 0.
667*f1fbf3c2SXin LiNote that the substituted code is not an expression but
668*f1fbf3c2SXin Lia statement or a block.  It cannot be or contain a try-catch statement.
669*f1fbf3c2SXin Li
670*f1fbf3c2SXin Li<p>The method <code>instrument()</code> searches a method body.
671*f1fbf3c2SXin LiIf it finds an expression such as a method call, field access, and object
672*f1fbf3c2SXin Licreation, then it calls <code>edit()</code> on the given
673*f1fbf3c2SXin Li<code>ExprEditor</code> object.  The parameter to <code>edit()</code>
674*f1fbf3c2SXin Liis an object representing the found expression.  The <code>edit()</code>
675*f1fbf3c2SXin Limethod can inspect and replace the expression through that object.
676*f1fbf3c2SXin Li
677*f1fbf3c2SXin Li<p>Calling <code>replace()</code> on the parameter to <code>edit()</code>
678*f1fbf3c2SXin Lisubstitutes the given statement or block for the expression.  If the given
679*f1fbf3c2SXin Liblock is an empty block, that is, if <code>replace("{}")</code>
680*f1fbf3c2SXin Liis executed, then the expression is removed from the method body.
681*f1fbf3c2SXin Li
682*f1fbf3c2SXin LiIf you want to insert a statement (or a block) before/after the
683*f1fbf3c2SXin Liexpression, a block like the following should be passed to
684*f1fbf3c2SXin Li<code>replace()</code>:
685*f1fbf3c2SXin Li
686*f1fbf3c2SXin Li<ul><pre>
687*f1fbf3c2SXin Li{ <em>before-statements;</em>
688*f1fbf3c2SXin Li  $_ = $proceed($$);
689*f1fbf3c2SXin Li  <em>after-statements;</em> }
690*f1fbf3c2SXin Li</pre></ul>
691*f1fbf3c2SXin Li
692*f1fbf3c2SXin Li<p>whichever the expression is either a method call, field access,
693*f1fbf3c2SXin Liobject creation, or others.  The second statement could be:
694*f1fbf3c2SXin Li
695*f1fbf3c2SXin Li<ul><pre>$_ = $proceed();</pre></ul>
696*f1fbf3c2SXin Li
697*f1fbf3c2SXin Li<p>if the expression is read access, or
698*f1fbf3c2SXin Li
699*f1fbf3c2SXin Li<ul><pre>$proceed($$);</pre></ul>
700*f1fbf3c2SXin Li
701*f1fbf3c2SXin Li<p>if the expression is write access.
702*f1fbf3c2SXin Li
703*f1fbf3c2SXin Li<p>Local variables available in the target expression is
704*f1fbf3c2SXin Lialso available in the source text passed to <code>replace()</code>
705*f1fbf3c2SXin Liif the method searched by <code>instrument()</code> was compiled
706*f1fbf3c2SXin Liwith the -g option (the class file includes a local variable
707*f1fbf3c2SXin Liattribute).
708*f1fbf3c2SXin Li
709*f1fbf3c2SXin Li<h4>javassist.expr.MethodCall</h4>
710*f1fbf3c2SXin Li
711*f1fbf3c2SXin Li<p>A <code>MethodCall</code> object represents a method call.
712*f1fbf3c2SXin LiThe method <code>replace()</code> in
713*f1fbf3c2SXin Li<code>MethodCall</code> substitutes a statement or
714*f1fbf3c2SXin Lia block for the method call.
715*f1fbf3c2SXin LiIt receives source text representing the substitued statement or
716*f1fbf3c2SXin Liblock, in which the identifiers starting with <code>$</code>
717*f1fbf3c2SXin Lihave special meaning as in the source text passed to
718*f1fbf3c2SXin Li<code>insertBefore()</code>.
719*f1fbf3c2SXin Li
720*f1fbf3c2SXin Li<ul><table border=0>
721*f1fbf3c2SXin Li<tr>
722*f1fbf3c2SXin Li<td><code>$0</code></td>
723*f1fbf3c2SXin Li<td rowspan=3>
724*f1fbf3c2SXin LiThe target object of the method call.<br>
725*f1fbf3c2SXin LiThis is not equivalent to <code>this</code>, which represents
726*f1fbf3c2SXin Lithe caller-side <code>this</code> object.<br>
727*f1fbf3c2SXin Li<code>$0</code> is <code>null</code> if the method is static.
728*f1fbf3c2SXin Li</td>
729*f1fbf3c2SXin Li</tr>
730*f1fbf3c2SXin Li
731*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
732*f1fbf3c2SXin Li
733*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
734*f1fbf3c2SXin Li
735*f1fbf3c2SXin Li<tr>
736*f1fbf3c2SXin Li<td><code>$1</code>, <code>$2</code>, ... &nbsp &nbsp</td>
737*f1fbf3c2SXin Li<td>
738*f1fbf3c2SXin LiThe parameters of the method call.
739*f1fbf3c2SXin Li</td>
740*f1fbf3c2SXin Li</tr>
741*f1fbf3c2SXin Li
742*f1fbf3c2SXin Li<tr><td>
743*f1fbf3c2SXin Li<code>$_</code></td>
744*f1fbf3c2SXin Li<td>The resulting value of the method call.</td>
745*f1fbf3c2SXin Li</tr>
746*f1fbf3c2SXin Li
747*f1fbf3c2SXin Li<tr><td><code>$r</code></td>
748*f1fbf3c2SXin Li<td>The result type of the method call.</td>
749*f1fbf3c2SXin Li</tr>
750*f1fbf3c2SXin Li
751*f1fbf3c2SXin Li<tr><td><code>$class</code> &nbsp &nbsp</td>
752*f1fbf3c2SXin Li<td>A <code>java.lang.Class</code> object representing
753*f1fbf3c2SXin Lithe class declaring the method.
754*f1fbf3c2SXin Li</td>
755*f1fbf3c2SXin Li</tr>
756*f1fbf3c2SXin Li
757*f1fbf3c2SXin Li<tr><td><code>$sig</code> &nbsp &nbsp</td>
758*f1fbf3c2SXin Li<td>An array of <code>java.lang.Class</code> objects representing
759*f1fbf3c2SXin Lithe formal parameter types.</td>
760*f1fbf3c2SXin Li</tr>
761*f1fbf3c2SXin Li
762*f1fbf3c2SXin Li<tr><td><code>$type</code> &nbsp &nbsp</td>
763*f1fbf3c2SXin Li<td>A <code>java.lang.Class</code> object representing
764*f1fbf3c2SXin Lithe formal result type.</td>
765*f1fbf3c2SXin Li</tr>
766*f1fbf3c2SXin Li
767*f1fbf3c2SXin Li<tr><td><code>$proceed</code> &nbsp &nbsp</td>
768*f1fbf3c2SXin Li<td>The name of the method originally called
769*f1fbf3c2SXin Liin the expression.</td>
770*f1fbf3c2SXin Li</tr>
771*f1fbf3c2SXin Li
772*f1fbf3c2SXin Li</table>
773*f1fbf3c2SXin Li</ul>
774*f1fbf3c2SXin Li
775*f1fbf3c2SXin Li<p>Here the method call means the one represented by the
776*f1fbf3c2SXin Li<code>MethodCall</code> object.
777*f1fbf3c2SXin Li
778*f1fbf3c2SXin Li<p>The other identifiers such as <code>$w</code>,
779*f1fbf3c2SXin Li<code>$args</code> and <code>$$</code>
780*f1fbf3c2SXin Liare also available.
781*f1fbf3c2SXin Li
782*f1fbf3c2SXin Li<p>Unless the result type of the method call is <code>void</code>,
783*f1fbf3c2SXin Lia value must be assigned to
784*f1fbf3c2SXin Li<code>$_</code> in the source text and the type of <code>$_</code>
785*f1fbf3c2SXin Liis the result type.
786*f1fbf3c2SXin LiIf the result type is <code>void</code>, the type of <code>$_</code>
787*f1fbf3c2SXin Liis <code>Object</code> and the value assigned to <code>$_</code>
788*f1fbf3c2SXin Liis ignored.
789*f1fbf3c2SXin Li
790*f1fbf3c2SXin Li<p><code>$proceed</code> is not a <code>String</code> value but special
791*f1fbf3c2SXin Lisyntax.  It must be followed by an argument list surrounded by parentheses
792*f1fbf3c2SXin Li<code>( )</code>.
793*f1fbf3c2SXin Li
794*f1fbf3c2SXin Li<h4>javassist.expr.ConstructorCall</h4>
795*f1fbf3c2SXin Li
796*f1fbf3c2SXin Li<p>A <code>ConstructorCall</code> object represents a constructor call
797*f1fbf3c2SXin Lisuch as <code>this()</code> and <code>super</code> included in a constructor
798*f1fbf3c2SXin Libody.
799*f1fbf3c2SXin LiThe method <code>replace()</code> in
800*f1fbf3c2SXin Li<code>ConstructorCall</code> substitutes a statement or
801*f1fbf3c2SXin Lia block for the constructor call.
802*f1fbf3c2SXin LiIt receives source text representing the substituted statement or
803*f1fbf3c2SXin Liblock, in which the identifiers starting with <code>$</code>
804*f1fbf3c2SXin Lihave special meaning as in the source text passed to
805*f1fbf3c2SXin Li<code>insertBefore()</code>.
806*f1fbf3c2SXin Li
807*f1fbf3c2SXin Li<ul><table border=0>
808*f1fbf3c2SXin Li<tr>
809*f1fbf3c2SXin Li<td><code>$0</code></td>
810*f1fbf3c2SXin Li<td>
811*f1fbf3c2SXin LiThe target object of the constructor call.
812*f1fbf3c2SXin LiThis is equivalent to <code>this</code>.
813*f1fbf3c2SXin Li</td>
814*f1fbf3c2SXin Li</tr>
815*f1fbf3c2SXin Li
816*f1fbf3c2SXin Li<tr>
817*f1fbf3c2SXin Li<td><code>$1</code>, <code>$2</code>, ... &nbsp &nbsp</td>
818*f1fbf3c2SXin Li<td>
819*f1fbf3c2SXin LiThe parameters of the constructor call.
820*f1fbf3c2SXin Li</td>
821*f1fbf3c2SXin Li</tr>
822*f1fbf3c2SXin Li
823*f1fbf3c2SXin Li<tr><td><code>$class</code> &nbsp &nbsp</td>
824*f1fbf3c2SXin Li<td>A <code>java.lang.Class</code> object representing
825*f1fbf3c2SXin Lithe class declaring the constructor.
826*f1fbf3c2SXin Li</td>
827*f1fbf3c2SXin Li</tr>
828*f1fbf3c2SXin Li
829*f1fbf3c2SXin Li<tr><td><code>$sig</code> &nbsp &nbsp</td>
830*f1fbf3c2SXin Li<td>An array of <code>java.lang.Class</code> objects representing
831*f1fbf3c2SXin Lithe formal parameter types.</td>
832*f1fbf3c2SXin Li</tr>
833*f1fbf3c2SXin Li
834*f1fbf3c2SXin Li<tr><td><code>$proceed</code> &nbsp &nbsp</td>
835*f1fbf3c2SXin Li<td>The name of the constructor originally called
836*f1fbf3c2SXin Liin the expression.</td>
837*f1fbf3c2SXin Li</tr>
838*f1fbf3c2SXin Li
839*f1fbf3c2SXin Li</table>
840*f1fbf3c2SXin Li</ul>
841*f1fbf3c2SXin Li
842*f1fbf3c2SXin Li<p>Here the constructor call means the one represented by the
843*f1fbf3c2SXin Li<code>ConstructorCall</code> object.
844*f1fbf3c2SXin Li
845*f1fbf3c2SXin Li<p>The other identifiers such as <code>$w</code>,
846*f1fbf3c2SXin Li<code>$args</code> and <code>$$</code>
847*f1fbf3c2SXin Liare also available.
848*f1fbf3c2SXin Li
849*f1fbf3c2SXin Li<p>Since any constructor must call either a constructor of the super
850*f1fbf3c2SXin Liclass or another constructor of the same class,
851*f1fbf3c2SXin Lithe substituted statement must include a constructor call,
852*f1fbf3c2SXin Linormally a call to <code>$proceed()</code>.
853*f1fbf3c2SXin Li
854*f1fbf3c2SXin Li<p><code>$proceed</code> is not a <code>String</code> value but special
855*f1fbf3c2SXin Lisyntax.  It must be followed by an argument list surrounded by parentheses
856*f1fbf3c2SXin Li<code>( )</code>.
857*f1fbf3c2SXin Li
858*f1fbf3c2SXin Li<h4>javassist.expr.FieldAccess</h4>
859*f1fbf3c2SXin Li
860*f1fbf3c2SXin Li<p>A <code>FieldAccess</code> object represents field access.
861*f1fbf3c2SXin LiThe method <code>edit()</code> in <code>ExprEditor</code>
862*f1fbf3c2SXin Lireceives this object if field access is found.
863*f1fbf3c2SXin LiThe method <code>replace()</code> in
864*f1fbf3c2SXin Li<code>FieldAccess</code> receives
865*f1fbf3c2SXin Lisource text representing the substitued statement or
866*f1fbf3c2SXin Liblock for the field access.
867*f1fbf3c2SXin Li
868*f1fbf3c2SXin Li<p>
869*f1fbf3c2SXin LiIn the source text, the identifiers starting with <code>$</code>
870*f1fbf3c2SXin Lihave special meaning:
871*f1fbf3c2SXin Li
872*f1fbf3c2SXin Li<ul><table border=0>
873*f1fbf3c2SXin Li<tr>
874*f1fbf3c2SXin Li<td><code>$0</code></td>
875*f1fbf3c2SXin Li<td rowspan=3>
876*f1fbf3c2SXin LiThe object containing the field accessed by the expression.
877*f1fbf3c2SXin LiThis is not equivalent to <code>this</code>.<br>
878*f1fbf3c2SXin Li<code>this</code> represents the object that the method including the
879*f1fbf3c2SXin Liexpression is invoked on.<br>
880*f1fbf3c2SXin Li<code>$0</code> is <code>null</code> if the field is static.
881*f1fbf3c2SXin Li</td>
882*f1fbf3c2SXin Li</tr>
883*f1fbf3c2SXin Li
884*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
885*f1fbf3c2SXin Li
886*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
887*f1fbf3c2SXin Li
888*f1fbf3c2SXin Li<tr>
889*f1fbf3c2SXin Li<td><code>$1</code></td>
890*f1fbf3c2SXin Li<td rowspan=2>
891*f1fbf3c2SXin LiThe value that would be stored in the field
892*f1fbf3c2SXin Liif the expression is write access.
893*f1fbf3c2SXin Li<br>Otherwise, <code>$1</code> is not available.
894*f1fbf3c2SXin Li</td>
895*f1fbf3c2SXin Li</tr>
896*f1fbf3c2SXin Li
897*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
898*f1fbf3c2SXin Li
899*f1fbf3c2SXin Li<tr>
900*f1fbf3c2SXin Li<td><code>$_</code></td>
901*f1fbf3c2SXin Li<td rowspan=2>
902*f1fbf3c2SXin LiThe resulting value of the field access
903*f1fbf3c2SXin Liif the expression is read access.
904*f1fbf3c2SXin Li<br>Otherwise, the value stored in <code>$_</code> is discarded.
905*f1fbf3c2SXin Li</td>
906*f1fbf3c2SXin Li</tr>
907*f1fbf3c2SXin Li
908*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
909*f1fbf3c2SXin Li<tr>
910*f1fbf3c2SXin Li<td><code>$r</code></td>
911*f1fbf3c2SXin Li<td rowspan=2>
912*f1fbf3c2SXin LiThe type of the field if the expression is read access.
913*f1fbf3c2SXin Li<br>Otherwise, <code>$r</code> is <code>void</code>.
914*f1fbf3c2SXin Li</td>
915*f1fbf3c2SXin Li</tr>
916*f1fbf3c2SXin Li
917*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
918*f1fbf3c2SXin Li
919*f1fbf3c2SXin Li<tr><td><code>$class</code> &nbsp &nbsp</td>
920*f1fbf3c2SXin Li<td>A <code>java.lang.Class</code> object representing
921*f1fbf3c2SXin Lithe class declaring the field.
922*f1fbf3c2SXin Li</td></tr>
923*f1fbf3c2SXin Li
924*f1fbf3c2SXin Li<tr><td><code>$type</code></td>
925*f1fbf3c2SXin Li<td>A <code>java.lang.Class</code> object representing
926*f1fbf3c2SXin Lithe field type.</td>
927*f1fbf3c2SXin Li</tr>
928*f1fbf3c2SXin Li
929*f1fbf3c2SXin Li<tr><td><code>$proceed</code> &nbsp &nbsp</td>
930*f1fbf3c2SXin Li<td>The name of a virtual method executing the original
931*f1fbf3c2SXin Lifield access.
932*f1fbf3c2SXin Li.</td>
933*f1fbf3c2SXin Li</tr>
934*f1fbf3c2SXin Li
935*f1fbf3c2SXin Li</table>
936*f1fbf3c2SXin Li</ul>
937*f1fbf3c2SXin Li
938*f1fbf3c2SXin Li<p>The other identifiers such as <code>$w</code>,
939*f1fbf3c2SXin Li<code>$args</code> and <code>$$</code>
940*f1fbf3c2SXin Liare also available.
941*f1fbf3c2SXin Li
942*f1fbf3c2SXin Li<p>If the expression is read access, a value must be assigned to
943*f1fbf3c2SXin Li<code>$_</code> in the source text.  The type of <code>$_</code>
944*f1fbf3c2SXin Liis the type of the field.
945*f1fbf3c2SXin Li
946*f1fbf3c2SXin Li<h4>javassist.expr.NewExpr</h4>
947*f1fbf3c2SXin Li
948*f1fbf3c2SXin Li<p>A <code>NewExpr</code> object represents object creation
949*f1fbf3c2SXin Liwith the <code>new</code> operator (not including array creation).
950*f1fbf3c2SXin LiThe method <code>edit()</code> in <code>ExprEditor</code>
951*f1fbf3c2SXin Lireceives this object if object creation is found.
952*f1fbf3c2SXin LiThe method <code>replace()</code> in
953*f1fbf3c2SXin Li<code>NewExpr</code> receives
954*f1fbf3c2SXin Lisource text representing the substitued statement or
955*f1fbf3c2SXin Liblock for the object creation.
956*f1fbf3c2SXin Li
957*f1fbf3c2SXin Li<p>
958*f1fbf3c2SXin LiIn the source text, the identifiers starting with <code>$</code>
959*f1fbf3c2SXin Lihave special meaning:
960*f1fbf3c2SXin Li
961*f1fbf3c2SXin Li<ul><table border=0>
962*f1fbf3c2SXin Li
963*f1fbf3c2SXin Li<tr>
964*f1fbf3c2SXin Li<td><code>$0</code></td>
965*f1fbf3c2SXin Li<td>
966*f1fbf3c2SXin Li<code>null</code>.
967*f1fbf3c2SXin Li</td>
968*f1fbf3c2SXin Li</tr>
969*f1fbf3c2SXin Li
970*f1fbf3c2SXin Li<tr>
971*f1fbf3c2SXin Li<td><code>$1</code>, <code>$2</code>, ... &nbsp &nbsp</td>
972*f1fbf3c2SXin Li<td>
973*f1fbf3c2SXin LiThe parameters to the constructor.
974*f1fbf3c2SXin Li</td>
975*f1fbf3c2SXin Li</tr>
976*f1fbf3c2SXin Li
977*f1fbf3c2SXin Li<tr>
978*f1fbf3c2SXin Li<td><code>$_</code></td>
979*f1fbf3c2SXin Li<td rowspan=2>
980*f1fbf3c2SXin LiThe resulting value of the object creation.
981*f1fbf3c2SXin Li<br>A newly created object must be stored in this variable.
982*f1fbf3c2SXin Li</td>
983*f1fbf3c2SXin Li</tr>
984*f1fbf3c2SXin Li
985*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
986*f1fbf3c2SXin Li
987*f1fbf3c2SXin Li<tr>
988*f1fbf3c2SXin Li<td><code>$r</code></td>
989*f1fbf3c2SXin Li<td>
990*f1fbf3c2SXin LiThe type of the created object.
991*f1fbf3c2SXin Li</td>
992*f1fbf3c2SXin Li</tr>
993*f1fbf3c2SXin Li
994*f1fbf3c2SXin Li<tr><td><code>$sig</code> &nbsp &nbsp</td>
995*f1fbf3c2SXin Li<td>An array of <code>java.lang.Class</code> objects representing
996*f1fbf3c2SXin Lithe formal parameter types.</td>
997*f1fbf3c2SXin Li</tr>
998*f1fbf3c2SXin Li
999*f1fbf3c2SXin Li<tr><td><code>$type</code> &nbsp &nbsp</td>
1000*f1fbf3c2SXin Li<td>A <code>java.lang.Class</code> object representing
1001*f1fbf3c2SXin Lithe class of the created object.
1002*f1fbf3c2SXin Li</td></tr>
1003*f1fbf3c2SXin Li
1004*f1fbf3c2SXin Li<tr><td><code>$proceed</code> &nbsp &nbsp</td>
1005*f1fbf3c2SXin Li<td>The name of a virtual method executing the original
1006*f1fbf3c2SXin Liobject creation.
1007*f1fbf3c2SXin Li.</td>
1008*f1fbf3c2SXin Li</tr>
1009*f1fbf3c2SXin Li
1010*f1fbf3c2SXin Li</table>
1011*f1fbf3c2SXin Li</ul>
1012*f1fbf3c2SXin Li
1013*f1fbf3c2SXin Li<p>The other identifiers such as <code>$w</code>,
1014*f1fbf3c2SXin Li<code>$args</code> and <code>$$</code>
1015*f1fbf3c2SXin Liare also available.
1016*f1fbf3c2SXin Li
1017*f1fbf3c2SXin Li<h4>javassist.expr.NewArray</h4>
1018*f1fbf3c2SXin Li
1019*f1fbf3c2SXin Li<p>A <code>NewArray</code> object represents array creation
1020*f1fbf3c2SXin Liwith the <code>new</code> operator.
1021*f1fbf3c2SXin LiThe method <code>edit()</code> in <code>ExprEditor</code>
1022*f1fbf3c2SXin Lireceives this object if array creation is found.
1023*f1fbf3c2SXin LiThe method <code>replace()</code> in
1024*f1fbf3c2SXin Li<code>NewArray</code> receives
1025*f1fbf3c2SXin Lisource text representing the substitued statement or
1026*f1fbf3c2SXin Liblock for the array creation.
1027*f1fbf3c2SXin Li
1028*f1fbf3c2SXin Li<p>
1029*f1fbf3c2SXin LiIn the source text, the identifiers starting with <code>$</code>
1030*f1fbf3c2SXin Lihave special meaning:
1031*f1fbf3c2SXin Li
1032*f1fbf3c2SXin Li<ul><table border=0>
1033*f1fbf3c2SXin Li
1034*f1fbf3c2SXin Li<tr>
1035*f1fbf3c2SXin Li<td><code>$0</code></td>
1036*f1fbf3c2SXin Li<td>
1037*f1fbf3c2SXin Li<code>null</code>.
1038*f1fbf3c2SXin Li</td>
1039*f1fbf3c2SXin Li</tr>
1040*f1fbf3c2SXin Li
1041*f1fbf3c2SXin Li<tr>
1042*f1fbf3c2SXin Li<td><code>$1</code>, <code>$2</code>, ... &nbsp &nbsp</td>
1043*f1fbf3c2SXin Li<td>
1044*f1fbf3c2SXin LiThe size of each dimension.
1045*f1fbf3c2SXin Li</td>
1046*f1fbf3c2SXin Li</tr>
1047*f1fbf3c2SXin Li
1048*f1fbf3c2SXin Li<tr>
1049*f1fbf3c2SXin Li<td><code>$_</code></td>
1050*f1fbf3c2SXin Li<td rowspan=2>
1051*f1fbf3c2SXin LiThe resulting value of the array creation.
1052*f1fbf3c2SXin Li<br>A newly created array must be stored in this variable.
1053*f1fbf3c2SXin Li</td>
1054*f1fbf3c2SXin Li</tr>
1055*f1fbf3c2SXin Li
1056*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
1057*f1fbf3c2SXin Li
1058*f1fbf3c2SXin Li<tr>
1059*f1fbf3c2SXin Li<td><code>$r</code></td>
1060*f1fbf3c2SXin Li<td>
1061*f1fbf3c2SXin LiThe type of the created array.
1062*f1fbf3c2SXin Li</td>
1063*f1fbf3c2SXin Li</tr>
1064*f1fbf3c2SXin Li
1065*f1fbf3c2SXin Li<tr><td><code>$type</code> &nbsp &nbsp</td>
1066*f1fbf3c2SXin Li<td>A <code>java.lang.Class</code> object representing
1067*f1fbf3c2SXin Lithe class of the created array.
1068*f1fbf3c2SXin Li</td></tr>
1069*f1fbf3c2SXin Li
1070*f1fbf3c2SXin Li<tr><td><code>$proceed</code> &nbsp &nbsp</td>
1071*f1fbf3c2SXin Li<td>The name of a virtual method executing the original
1072*f1fbf3c2SXin Liarray creation.
1073*f1fbf3c2SXin Li.</td>
1074*f1fbf3c2SXin Li</tr>
1075*f1fbf3c2SXin Li
1076*f1fbf3c2SXin Li</table>
1077*f1fbf3c2SXin Li</ul>
1078*f1fbf3c2SXin Li
1079*f1fbf3c2SXin Li<p>The other identifiers such as <code>$w</code>,
1080*f1fbf3c2SXin Li<code>$args</code> and <code>$$</code>
1081*f1fbf3c2SXin Liare also available.
1082*f1fbf3c2SXin Li
1083*f1fbf3c2SXin Li<p>For example, if the array creation is the following expression,
1084*f1fbf3c2SXin Li
1085*f1fbf3c2SXin Li<ul><pre>
1086*f1fbf3c2SXin LiString[][] s = new String[3][4];
1087*f1fbf3c2SXin Li</pre></ul>
1088*f1fbf3c2SXin Li
1089*f1fbf3c2SXin Lithen the value of $1 and $2 are 3 and 4, respectively.  $3 is not available.
1090*f1fbf3c2SXin Li
1091*f1fbf3c2SXin Li<p>If the array creation is the following expression,
1092*f1fbf3c2SXin Li
1093*f1fbf3c2SXin Li<ul><pre>
1094*f1fbf3c2SXin LiString[][] s = new String[3][];
1095*f1fbf3c2SXin Li</pre></ul>
1096*f1fbf3c2SXin Li
1097*f1fbf3c2SXin Lithen the value of $1 is 3 but $2 is not available.
1098*f1fbf3c2SXin Li
1099*f1fbf3c2SXin Li<h4>javassist.expr.Instanceof</h4>
1100*f1fbf3c2SXin Li
1101*f1fbf3c2SXin Li<p>A <code>Instanceof</code> object represents an <code>instanceof</code>
1102*f1fbf3c2SXin Liexpression.
1103*f1fbf3c2SXin LiThe method <code>edit()</code> in <code>ExprEditor</code>
1104*f1fbf3c2SXin Lireceives this object if an instanceof expression is found.
1105*f1fbf3c2SXin LiThe method <code>replace()</code> in
1106*f1fbf3c2SXin Li<code>Instanceof</code> receives
1107*f1fbf3c2SXin Lisource text representing the substitued statement or
1108*f1fbf3c2SXin Liblock for the expression.
1109*f1fbf3c2SXin Li
1110*f1fbf3c2SXin Li<p>
1111*f1fbf3c2SXin LiIn the source text, the identifiers starting with <code>$</code>
1112*f1fbf3c2SXin Lihave special meaning:
1113*f1fbf3c2SXin Li
1114*f1fbf3c2SXin Li<ul><table border=0>
1115*f1fbf3c2SXin Li
1116*f1fbf3c2SXin Li<tr>
1117*f1fbf3c2SXin Li<td><code>$0</code></td>
1118*f1fbf3c2SXin Li<td>
1119*f1fbf3c2SXin Li<code>null</code>.
1120*f1fbf3c2SXin Li</td>
1121*f1fbf3c2SXin Li</tr>
1122*f1fbf3c2SXin Li
1123*f1fbf3c2SXin Li<tr>
1124*f1fbf3c2SXin Li<td><code>$1</code></td>
1125*f1fbf3c2SXin Li<td>
1126*f1fbf3c2SXin LiThe value on the left hand side of the original
1127*f1fbf3c2SXin Li<code>instanceof</code> operator.
1128*f1fbf3c2SXin Li</td>
1129*f1fbf3c2SXin Li</tr>
1130*f1fbf3c2SXin Li
1131*f1fbf3c2SXin Li<tr>
1132*f1fbf3c2SXin Li<td><code>$_</code></td>
1133*f1fbf3c2SXin Li<td>
1134*f1fbf3c2SXin LiThe resulting value of the expression.
1135*f1fbf3c2SXin LiThe type of <code>$_</code> is <code>boolean</code>.
1136*f1fbf3c2SXin Li</td>
1137*f1fbf3c2SXin Li</tr>
1138*f1fbf3c2SXin Li
1139*f1fbf3c2SXin Li<tr>
1140*f1fbf3c2SXin Li<td><code>$r</code></td>
1141*f1fbf3c2SXin Li<td>
1142*f1fbf3c2SXin LiThe type on the right hand side of the <code>instanceof</code> operator.
1143*f1fbf3c2SXin Li</td>
1144*f1fbf3c2SXin Li</tr>
1145*f1fbf3c2SXin Li
1146*f1fbf3c2SXin Li<tr><td><code>$type</code></td>
1147*f1fbf3c2SXin Li<td>A <code>java.lang.Class</code> object representing
1148*f1fbf3c2SXin Lithe type on the right hand side of the <code>instanceof</code> operator.
1149*f1fbf3c2SXin Li</td>
1150*f1fbf3c2SXin Li</tr>
1151*f1fbf3c2SXin Li
1152*f1fbf3c2SXin Li<tr><td><code>$proceed</code> &nbsp &nbsp</td>
1153*f1fbf3c2SXin Li<td rowspan=4>The name of a virtual method executing the original
1154*f1fbf3c2SXin Li<code>instanceof</code> expression.
1155*f1fbf3c2SXin Li<br>It takes one parameter (the type is <code>java.lang.Object</code>)
1156*f1fbf3c2SXin Liand returns true
1157*f1fbf3c2SXin Li<br>if the parameter value is an instance of the type on the right
1158*f1fbf3c2SXin Lihand side of
1159*f1fbf3c2SXin Li<br>the original <code>instanceof</code> operator.
1160*f1fbf3c2SXin LiOtherwise, it returns false.
1161*f1fbf3c2SXin Li</td>
1162*f1fbf3c2SXin Li</tr>
1163*f1fbf3c2SXin Li
1164*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
1165*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
1166*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
1167*f1fbf3c2SXin Li
1168*f1fbf3c2SXin Li</table>
1169*f1fbf3c2SXin Li</ul>
1170*f1fbf3c2SXin Li
1171*f1fbf3c2SXin Li<p>The other identifiers such as <code>$w</code>,
1172*f1fbf3c2SXin Li<code>$args</code> and <code>$$</code>
1173*f1fbf3c2SXin Liare also available.
1174*f1fbf3c2SXin Li
1175*f1fbf3c2SXin Li<h4>javassist.expr.Cast</h4>
1176*f1fbf3c2SXin Li
1177*f1fbf3c2SXin Li<p>A <code>Cast</code> object represents an expression for
1178*f1fbf3c2SXin Liexplicit type casting.
1179*f1fbf3c2SXin LiThe method <code>edit()</code> in <code>ExprEditor</code>
1180*f1fbf3c2SXin Lireceives this object if explicit type casting is found.
1181*f1fbf3c2SXin LiThe method <code>replace()</code> in
1182*f1fbf3c2SXin Li<code>Cast</code> receives
1183*f1fbf3c2SXin Lisource text representing the substitued statement or
1184*f1fbf3c2SXin Liblock for the expression.
1185*f1fbf3c2SXin Li
1186*f1fbf3c2SXin Li<p>
1187*f1fbf3c2SXin LiIn the source text, the identifiers starting with <code>$</code>
1188*f1fbf3c2SXin Lihave special meaning:
1189*f1fbf3c2SXin Li
1190*f1fbf3c2SXin Li<ul><table border=0>
1191*f1fbf3c2SXin Li
1192*f1fbf3c2SXin Li<tr>
1193*f1fbf3c2SXin Li<td><code>$0</code></td>
1194*f1fbf3c2SXin Li<td>
1195*f1fbf3c2SXin Li<code>null</code>.
1196*f1fbf3c2SXin Li</td>
1197*f1fbf3c2SXin Li</tr>
1198*f1fbf3c2SXin Li
1199*f1fbf3c2SXin Li<tr>
1200*f1fbf3c2SXin Li<td><code>$1</code></td>
1201*f1fbf3c2SXin Li<td>
1202*f1fbf3c2SXin LiThe value the type of which is explicitly cast.
1203*f1fbf3c2SXin Li</td>
1204*f1fbf3c2SXin Li</tr>
1205*f1fbf3c2SXin Li
1206*f1fbf3c2SXin Li<tr>
1207*f1fbf3c2SXin Li<td><code>$_</code></td>
1208*f1fbf3c2SXin Li<td rowspan=2>
1209*f1fbf3c2SXin LiThe resulting value of the expression.
1210*f1fbf3c2SXin LiThe type of <code>$_</code> is the same as the type
1211*f1fbf3c2SXin Li<br>after the explicit casting, that is, the type surrounded
1212*f1fbf3c2SXin Liby <code>( )</code>.
1213*f1fbf3c2SXin Li</td>
1214*f1fbf3c2SXin Li</tr>
1215*f1fbf3c2SXin Li
1216*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
1217*f1fbf3c2SXin Li
1218*f1fbf3c2SXin Li<tr>
1219*f1fbf3c2SXin Li<td><code>$r</code></td>
1220*f1fbf3c2SXin Li<td>the type after the explicit casting, or the type surrounded
1221*f1fbf3c2SXin Liby <code>( )</code>.
1222*f1fbf3c2SXin Li</td>
1223*f1fbf3c2SXin Li</tr>
1224*f1fbf3c2SXin Li
1225*f1fbf3c2SXin Li<tr><td><code>$type</code></td>
1226*f1fbf3c2SXin Li<td>A <code>java.lang.Class</code> object representing
1227*f1fbf3c2SXin Lithe same type as <code>$r</code>.
1228*f1fbf3c2SXin Li</td>
1229*f1fbf3c2SXin Li</tr>
1230*f1fbf3c2SXin Li
1231*f1fbf3c2SXin Li<tr><td><code>$proceed</code> &nbsp &nbsp</td>
1232*f1fbf3c2SXin Li<td rowspan=3>The name of a virtual method executing the original
1233*f1fbf3c2SXin Litype casting.
1234*f1fbf3c2SXin Li<br>It takes one parameter of the type <code>java.lang.Object</code>
1235*f1fbf3c2SXin Liand returns it after
1236*f1fbf3c2SXin Li<br>the explicit type casting specified by the original expression.
1237*f1fbf3c2SXin Li
1238*f1fbf3c2SXin Li</td>
1239*f1fbf3c2SXin Li</tr>
1240*f1fbf3c2SXin Li
1241*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
1242*f1fbf3c2SXin Li
1243*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
1244*f1fbf3c2SXin Li
1245*f1fbf3c2SXin Li</table>
1246*f1fbf3c2SXin Li</ul>
1247*f1fbf3c2SXin Li
1248*f1fbf3c2SXin Li<p>The other identifiers such as <code>$w</code>,
1249*f1fbf3c2SXin Li<code>$args</code> and <code>$$</code>
1250*f1fbf3c2SXin Liare also available.
1251*f1fbf3c2SXin Li
1252*f1fbf3c2SXin Li<h4>javassist.expr.Handler</h4>
1253*f1fbf3c2SXin Li
1254*f1fbf3c2SXin Li<p>A <code>Handler</code> object represents a <code>catch</code>
1255*f1fbf3c2SXin Liclause of <code>try-catch</code> statement.
1256*f1fbf3c2SXin LiThe method <code>edit()</code> in <code>ExprEditor</code>
1257*f1fbf3c2SXin Lireceives this object if a <code>catch</code> is found.
1258*f1fbf3c2SXin LiThe method <code>insertBefore()</code> in
1259*f1fbf3c2SXin Li<code>Handler</code> compiles the received
1260*f1fbf3c2SXin Lisource text and inserts it at the beginning of the <code>catch</code> clause.
1261*f1fbf3c2SXin Li
1262*f1fbf3c2SXin Li<p>
1263*f1fbf3c2SXin LiIn the source text, the identifiers starting with <code>$</code>
1264*f1fbf3c2SXin Lihave meaning:
1265*f1fbf3c2SXin Li
1266*f1fbf3c2SXin Li<ul><table border=0>
1267*f1fbf3c2SXin Li
1268*f1fbf3c2SXin Li<tr>
1269*f1fbf3c2SXin Li<td><code>$1</code></td>
1270*f1fbf3c2SXin Li<td>
1271*f1fbf3c2SXin LiThe exception object caught by the <code>catch</code> clause.
1272*f1fbf3c2SXin Li</td>
1273*f1fbf3c2SXin Li</tr>
1274*f1fbf3c2SXin Li
1275*f1fbf3c2SXin Li<tr>
1276*f1fbf3c2SXin Li<td><code>$r</code></td>
1277*f1fbf3c2SXin Li<td>the type of the exception caught by the <code>catch</code> clause.
1278*f1fbf3c2SXin LiIt is used in a cast expression.
1279*f1fbf3c2SXin Li</td>
1280*f1fbf3c2SXin Li</tr>
1281*f1fbf3c2SXin Li
1282*f1fbf3c2SXin Li<tr>
1283*f1fbf3c2SXin Li<td><code>$w</code></td>
1284*f1fbf3c2SXin Li<td>The wrapper type.  It is used in a cast expression.
1285*f1fbf3c2SXin Li</td>
1286*f1fbf3c2SXin Li</tr>
1287*f1fbf3c2SXin Li
1288*f1fbf3c2SXin Li<tr><td><code>$type</code> &nbsp &nbsp</td>
1289*f1fbf3c2SXin Li<td rowspan=2>
1290*f1fbf3c2SXin LiA <code>java.lang.Class</code> object representing
1291*f1fbf3c2SXin Li<br>the type of the exception caught by the <code>catch</code> clause.
1292*f1fbf3c2SXin Li</td>
1293*f1fbf3c2SXin Li</tr>
1294*f1fbf3c2SXin Li
1295*f1fbf3c2SXin Li<tr><td>&nbsp</td></tr>
1296*f1fbf3c2SXin Li
1297*f1fbf3c2SXin Li</table>
1298*f1fbf3c2SXin Li</ul>
1299*f1fbf3c2SXin Li
1300*f1fbf3c2SXin Li<p>If a new exception object is assigned to <code>$1</code>,
1301*f1fbf3c2SXin Liit is passed to the original <code>catch</code> clause as the caught
1302*f1fbf3c2SXin Liexception.
1303*f1fbf3c2SXin Li
1304*f1fbf3c2SXin Li<p><br>
1305*f1fbf3c2SXin Li
1306*f1fbf3c2SXin Li<a name="add">
1307*f1fbf3c2SXin Li<h3>4.3 Adding a new method or field</h3>
1308*f1fbf3c2SXin Li
1309*f1fbf3c2SXin Li<h4>Adding a method</h4>
1310*f1fbf3c2SXin Li
1311*f1fbf3c2SXin Li<p>Javassist allows the users to create a new method and constructor
1312*f1fbf3c2SXin Lifrom scratch.  <code>CtNewMethod</code>
1313*f1fbf3c2SXin Liand <code>CtNewConstructor</code> provide several factory methods,
1314*f1fbf3c2SXin Liwhich are static methods for creating <code>CtMethod</code> or
1315*f1fbf3c2SXin Li<code>CtConstructor</code> objects.
1316*f1fbf3c2SXin LiEspecially, <code>make()</code> creates
1317*f1fbf3c2SXin Lia <code>CtMethod</code> or <code>CtConstructor</code> object
1318*f1fbf3c2SXin Lifrom the given source text.
1319*f1fbf3c2SXin Li
1320*f1fbf3c2SXin Li<p>For example, this program:
1321*f1fbf3c2SXin Li
1322*f1fbf3c2SXin Li<ul><pre>
1323*f1fbf3c2SXin LiCtClass point = ClassPool.getDefault().get("Point");
1324*f1fbf3c2SXin LiCtMethod m = CtNewMethod.make(
1325*f1fbf3c2SXin Li                 "public int xmove(int dx) { x += dx; }",
1326*f1fbf3c2SXin Li                 point);
1327*f1fbf3c2SXin Lipoint.addMethod(m);
1328*f1fbf3c2SXin Li</pre></ul>
1329*f1fbf3c2SXin Li
1330*f1fbf3c2SXin Li<p>adds a public method <code>xmove()</code> to class <code>Point</code>.
1331*f1fbf3c2SXin LiIn this example, <code>x</code> is a <code>int</code> field in
1332*f1fbf3c2SXin Lithe class <code>Point</code>.
1333*f1fbf3c2SXin Li
1334*f1fbf3c2SXin Li<p>The source text passed to <code>make()</code> can include the
1335*f1fbf3c2SXin Liidentifiers starting with <code>$</code> except <code>$_</code>
1336*f1fbf3c2SXin Lias in <code>setBody()</code>.
1337*f1fbf3c2SXin LiIt can also include
1338*f1fbf3c2SXin Li<code>$proceed</code> if the target object and the target method name
1339*f1fbf3c2SXin Liare also given to <code>make()</code>.  For example,
1340*f1fbf3c2SXin Li
1341*f1fbf3c2SXin Li<ul><pre>
1342*f1fbf3c2SXin LiCtClass point = ClassPool.getDefault().get("Point");
1343*f1fbf3c2SXin LiCtMethod m = CtNewMethod.make(
1344*f1fbf3c2SXin Li                 "public int ymove(int dy) { $proceed(0, dy); }",
1345*f1fbf3c2SXin Li                 point, "this", "move");
1346*f1fbf3c2SXin Li</pre></ul>
1347*f1fbf3c2SXin Li
1348*f1fbf3c2SXin Li<p>this program creates a method <code>ymove()</code> defined below:
1349*f1fbf3c2SXin Li
1350*f1fbf3c2SXin Li<ul><pre>
1351*f1fbf3c2SXin Lipublic int ymove(int dy) { this.move(0, dy); }
1352*f1fbf3c2SXin Li</pre></ul>
1353*f1fbf3c2SXin Li
1354*f1fbf3c2SXin Li<p>Note that <code>$proceed</code> has been replaced with
1355*f1fbf3c2SXin Li<code>this.move</code>.
1356*f1fbf3c2SXin Li
1357*f1fbf3c2SXin Li<p>Javassist provides another way to add a new method.
1358*f1fbf3c2SXin LiYou can first create an abstract method and later give it a method body:
1359*f1fbf3c2SXin Li
1360*f1fbf3c2SXin Li<ul><pre>
1361*f1fbf3c2SXin LiCtClass cc = ... ;
1362*f1fbf3c2SXin LiCtMethod m = new CtMethod(CtClass.intType, "move",
1363*f1fbf3c2SXin Li                          new CtClass[] { CtClass.intType }, cc);
1364*f1fbf3c2SXin Licc.addMethod(m);
1365*f1fbf3c2SXin Lim.setBody("{ x += $1; }");
1366*f1fbf3c2SXin Licc.setModifiers(cc.getModifiers() & ~Modifier.ABSTRACT);
1367*f1fbf3c2SXin Li</pre></ul>
1368*f1fbf3c2SXin Li
1369*f1fbf3c2SXin Li<p>Since Javassist makes a class abstract if an abstract method is
1370*f1fbf3c2SXin Liadded to the class, you have to explicitly change the class back to a
1371*f1fbf3c2SXin Linon-abstract one after calling <code>setBody()</code>.
1372*f1fbf3c2SXin Li
1373*f1fbf3c2SXin Li
1374*f1fbf3c2SXin Li<h4>Mutual recursive methods</h4>
1375*f1fbf3c2SXin Li
1376*f1fbf3c2SXin Li<p>Javassist cannot compile a method if it calls another method that
1377*f1fbf3c2SXin Lihas not been added to a class.  (Javassist can compile a method that
1378*f1fbf3c2SXin Licalls itself recursively.)  To add mutual recursive methods to a class,
1379*f1fbf3c2SXin Liyou need a trick shown below.  Suppose that you want to add methods
1380*f1fbf3c2SXin Li<code>m()</code> and <code>n()</code> to a class represented
1381*f1fbf3c2SXin Liby <code>cc</code>:
1382*f1fbf3c2SXin Li
1383*f1fbf3c2SXin Li<ul><pre>
1384*f1fbf3c2SXin LiCtClass cc = ... ;
1385*f1fbf3c2SXin LiCtMethod m = CtNewMethod.make("public abstract int m(int i);", cc);
1386*f1fbf3c2SXin LiCtMethod n = CtNewMethod.make("public abstract int n(int i);", cc);
1387*f1fbf3c2SXin Licc.addMethod(m);
1388*f1fbf3c2SXin Licc.addMethod(n);
1389*f1fbf3c2SXin Lim.setBody("{ return ($1 <= 0) ? 1 : (n($1 - 1) * $1); }");
1390*f1fbf3c2SXin Lin.setBody("{ return m($1); }");
1391*f1fbf3c2SXin Licc.setModifiers(cc.getModifiers() & ~Modifier.ABSTRACT);
1392*f1fbf3c2SXin Li</pre></ul>
1393*f1fbf3c2SXin Li
1394*f1fbf3c2SXin Li<p>You must first make two abstract methods and add them to the class.
1395*f1fbf3c2SXin LiThen you can give the method bodies to these methods even if the method
1396*f1fbf3c2SXin Libodies include method calls to each other.  Finally you must change the
1397*f1fbf3c2SXin Liclass to a not-abstract class since <code>addMethod()</code> automatically
1398*f1fbf3c2SXin Lichanges a class into an abstract one if an abstract method is added.
1399*f1fbf3c2SXin Li
1400*f1fbf3c2SXin Li<h4>Adding a field</h4>
1401*f1fbf3c2SXin Li
1402*f1fbf3c2SXin Li<p>Javassist also allows the users to create a new field.
1403*f1fbf3c2SXin Li
1404*f1fbf3c2SXin Li<ul><pre>
1405*f1fbf3c2SXin LiCtClass point = ClassPool.getDefault().get("Point");
1406*f1fbf3c2SXin LiCtField f = new CtField(CtClass.intType, "z", point);
1407*f1fbf3c2SXin Lipoint.addField(f);
1408*f1fbf3c2SXin Li</pre></ul>
1409*f1fbf3c2SXin Li
1410*f1fbf3c2SXin Li<p>This program adds a field named <code>z</code> to class
1411*f1fbf3c2SXin Li<code>Point</code>.
1412*f1fbf3c2SXin Li
1413*f1fbf3c2SXin Li<p>If the initial value of the added field must be specified,
1414*f1fbf3c2SXin Lithe program shown above must be modified into:
1415*f1fbf3c2SXin Li
1416*f1fbf3c2SXin Li<ul><pre>
1417*f1fbf3c2SXin LiCtClass point = ClassPool.getDefault().get("Point");
1418*f1fbf3c2SXin LiCtField f = new CtField(CtClass.intType, "z", point);
1419*f1fbf3c2SXin Lipoint.addField(f, "0");    <em>// initial value is 0.</em>
1420*f1fbf3c2SXin Li</pre></ul>
1421*f1fbf3c2SXin Li
1422*f1fbf3c2SXin Li<p>Now, the method <code>addField()</code> receives the second parameter,
1423*f1fbf3c2SXin Liwhich is the source text representing an expression computing the initial
1424*f1fbf3c2SXin Livalue.  This source text can be any Java expression if the result type
1425*f1fbf3c2SXin Liof the expression matches the type of the field.  Note that an expression
1426*f1fbf3c2SXin Lidoes not end with a semi colon (<code>;</code>).
1427*f1fbf3c2SXin Li
1428*f1fbf3c2SXin Li<p>Furthermore, the above code can be rewritten into the following
1429*f1fbf3c2SXin Lisimple code:
1430*f1fbf3c2SXin Li
1431*f1fbf3c2SXin Li<ul><pre>
1432*f1fbf3c2SXin LiCtClass point = ClassPool.getDefault().get("Point");
1433*f1fbf3c2SXin LiCtField f = CtField.make("public int z = 0;", point);
1434*f1fbf3c2SXin Lipoint.addField(f);
1435*f1fbf3c2SXin Li</pre></ul>
1436*f1fbf3c2SXin Li
1437*f1fbf3c2SXin Li<h4>Removing a member</h4>
1438*f1fbf3c2SXin Li
1439*f1fbf3c2SXin Li<p>To remove a field or a method, call <code>removeField()</code>
1440*f1fbf3c2SXin Lior <code>removeMethod()</code> in <code>CtClass</code>.  A
1441*f1fbf3c2SXin Li<code>CtConstructor</code> can be removed by <code>removeConstructor()</code>
1442*f1fbf3c2SXin Liin <code>CtClass</code>.
1443*f1fbf3c2SXin Li
1444*f1fbf3c2SXin Li<p><br>
1445*f1fbf3c2SXin Li
1446*f1fbf3c2SXin Li<a name="annotation">
1447*f1fbf3c2SXin Li<h3>4.4 Annotations</h3>
1448*f1fbf3c2SXin Li
1449*f1fbf3c2SXin Li<p><code>CtClass</code>, <code>CtMethod</code>, <code>CtField</code>
1450*f1fbf3c2SXin Liand <code>CtConstructor</code> provides a convenient method
1451*f1fbf3c2SXin Li<code>getAnnotations()</code> for reading annotations.
1452*f1fbf3c2SXin LiIt returns an annotation-type object.
1453*f1fbf3c2SXin Li
1454*f1fbf3c2SXin Li<p>For example, suppose the following annotation:
1455*f1fbf3c2SXin Li
1456*f1fbf3c2SXin Li<ul><pre>
1457*f1fbf3c2SXin Lipublic @interface Author {
1458*f1fbf3c2SXin Li    String name();
1459*f1fbf3c2SXin Li    int year();
1460*f1fbf3c2SXin Li}
1461*f1fbf3c2SXin Li</pre></ul>
1462*f1fbf3c2SXin Li
1463*f1fbf3c2SXin Li<p>This annotation is used as the following:
1464*f1fbf3c2SXin Li
1465*f1fbf3c2SXin Li<ul><pre>
1466*f1fbf3c2SXin Li@Author(name="Chiba", year=2005)
1467*f1fbf3c2SXin Lipublic class Point {
1468*f1fbf3c2SXin Li    int x, y;
1469*f1fbf3c2SXin Li}
1470*f1fbf3c2SXin Li</pre></ul>
1471*f1fbf3c2SXin Li
1472*f1fbf3c2SXin Li<p>Then, the value of the annotation can be obtained by
1473*f1fbf3c2SXin Li<code>getAnnotations()</code>.
1474*f1fbf3c2SXin LiIt returns an array containing
1475*f1fbf3c2SXin Liannotation-type objects.
1476*f1fbf3c2SXin Li
1477*f1fbf3c2SXin Li<ul><pre>
1478*f1fbf3c2SXin LiCtClass cc = ClassPool.getDefault().get("Point");
1479*f1fbf3c2SXin LiObject[] all = cc.getAnnotations();
1480*f1fbf3c2SXin LiAuthor a = (Author)all[0];
1481*f1fbf3c2SXin LiString name = a.name();
1482*f1fbf3c2SXin Liint year = a.year();
1483*f1fbf3c2SXin LiSystem.out.println("name: " + name + ", year: " + year);
1484*f1fbf3c2SXin Li</pre></ul>
1485*f1fbf3c2SXin Li
1486*f1fbf3c2SXin Li<p>This code snippet should print:
1487*f1fbf3c2SXin Li
1488*f1fbf3c2SXin Li<ul><pre>
1489*f1fbf3c2SXin Liname: Chiba, year: 2005
1490*f1fbf3c2SXin Li</pre></ul>
1491*f1fbf3c2SXin Li
1492*f1fbf3c2SXin Li<p>
1493*f1fbf3c2SXin LiSince the annoation of <code>Point</code> is only <code>@Author</code>,
1494*f1fbf3c2SXin Lithe length of the array <code>all</code> is one
1495*f1fbf3c2SXin Liand <code>all[0]</code> is an <code>Author</code> object.
1496*f1fbf3c2SXin LiThe member values of the annotation can be obtained
1497*f1fbf3c2SXin Liby calling <code>name()</code> and <code>year()</code>
1498*f1fbf3c2SXin Lion the <code>Author</code> object.
1499*f1fbf3c2SXin Li
1500*f1fbf3c2SXin Li<p>To use <code>getAnnotations()</code>, annotation types
1501*f1fbf3c2SXin Lisuch as <code>Author</code> must be included in the current
1502*f1fbf3c2SXin Liclass path.  <em>They must be also accessible from a
1503*f1fbf3c2SXin Li<code>ClassPool</code> object.</em>  If the class file of an annotation
1504*f1fbf3c2SXin Litype is not found, Javassist cannot obtain the default values
1505*f1fbf3c2SXin Liof the members of that annotation type.
1506*f1fbf3c2SXin Li
1507*f1fbf3c2SXin Li<p><br>
1508*f1fbf3c2SXin Li
1509*f1fbf3c2SXin Li<a name="runtime">
1510*f1fbf3c2SXin Li<h3>4.5 Runtime support classes</h3>
1511*f1fbf3c2SXin Li
1512*f1fbf3c2SXin Li<p>In most cases, a class modified by Javassist does not require
1513*f1fbf3c2SXin LiJavassist to run.  However, some kinds of bytecode generated by the
1514*f1fbf3c2SXin LiJavassist compiler need runtime support classes, which are in the
1515*f1fbf3c2SXin Li<code>javassist.runtime</code> package (for details, please read
1516*f1fbf3c2SXin Lithe API reference of that package).  Note that the
1517*f1fbf3c2SXin Li<code>javassist.runtime</code> package is the only package that
1518*f1fbf3c2SXin Liclasses modified by Javassist may need for running.  The other
1519*f1fbf3c2SXin LiJavassist classes are never used at runtime of the modified classes.
1520*f1fbf3c2SXin Li
1521*f1fbf3c2SXin Li<p><br>
1522*f1fbf3c2SXin Li
1523*f1fbf3c2SXin Li<a name="import">
1524*f1fbf3c2SXin Li<h3>4.6 Import</h3>
1525*f1fbf3c2SXin Li
1526*f1fbf3c2SXin Li<p>All the class names in source code must be fully qualified
1527*f1fbf3c2SXin Li(they must include package names).
1528*f1fbf3c2SXin LiHowever, the <code>java.lang</code> package is an
1529*f1fbf3c2SXin Liexception; for example, the Javassist compiler can
1530*f1fbf3c2SXin Liresolve <code>Object</code> as
1531*f1fbf3c2SXin Liwell as <code>java.lang.Object</code>.
1532*f1fbf3c2SXin Li
1533*f1fbf3c2SXin Li<p>To tell the compiler to search other packages when resolving a
1534*f1fbf3c2SXin Liclass name, call <code>importPackage()</code> in <code>ClassPool</code>.
1535*f1fbf3c2SXin LiFor example,
1536*f1fbf3c2SXin Li
1537*f1fbf3c2SXin Li<ul><pre>
1538*f1fbf3c2SXin LiClassPool pool = ClassPool.getDefault();
1539*f1fbf3c2SXin Lipool.importPackage("java.awt");
1540*f1fbf3c2SXin LiCtClass cc = pool.makeClass("Test");
1541*f1fbf3c2SXin LiCtField f = CtField.make("public Point p;", cc);
1542*f1fbf3c2SXin Licc.addField(f);
1543*f1fbf3c2SXin Li</pre></ul>
1544*f1fbf3c2SXin Li
1545*f1fbf3c2SXin Li<p>The seconde line instructs the compiler
1546*f1fbf3c2SXin Lito import the <code>java.awt</code> package.
1547*f1fbf3c2SXin LiThus, the third line will not throw an exception.
1548*f1fbf3c2SXin LiThe compiler can recognize <code>Point</code>
1549*f1fbf3c2SXin Lias <code>java.awt.Point</code>.
1550*f1fbf3c2SXin Li
1551*f1fbf3c2SXin Li<p>Note that <code>importPackage()</code> <em>does not</em> affect
1552*f1fbf3c2SXin Lithe <code>get()</code> method in <code>ClassPool</code>.
1553*f1fbf3c2SXin LiOnly the compiler considers the imported packages.
1554*f1fbf3c2SXin LiThe parameter to <code>get()</code>
1555*f1fbf3c2SXin Limust be always a fully qualified name.
1556*f1fbf3c2SXin Li
1557*f1fbf3c2SXin Li<p><br>
1558*f1fbf3c2SXin Li
1559*f1fbf3c2SXin Li<a name="limit">
1560*f1fbf3c2SXin Li<h3>4.7 Limitations</h3>
1561*f1fbf3c2SXin Li
1562*f1fbf3c2SXin Li<p>In the current implementation, the Java compiler included in Javassist
1563*f1fbf3c2SXin Lihas several limitations with respect to the language that the compiler can
1564*f1fbf3c2SXin Liaccept.  Those limitations are:
1565*f1fbf3c2SXin Li
1566*f1fbf3c2SXin Li<p><li>The new syntax introduced by J2SE 5.0 (including enums and generics)
1567*f1fbf3c2SXin Lihas not been supported.  Annotations are supported by the low level
1568*f1fbf3c2SXin LiAPI of Javassist.
1569*f1fbf3c2SXin LiSee the <code>javassist.bytecode.annotation</code> package
1570*f1fbf3c2SXin Li(and also <code>getAnnotations()</code>
1571*f1fbf3c2SXin Liin <code>CtClass</code> and <code>CtBehavior</code>).
1572*f1fbf3c2SXin LiGenerics are also only partly supported.  See <a href="./tutorial3.html#generics">the latter section</a> for more details.
1573*f1fbf3c2SXin Li
1574*f1fbf3c2SXin Li<p><li>Array initializers, a comma-separated list of expressions
1575*f1fbf3c2SXin Lienclosed by braces <code>{</code> and <code>}</code>, are not
1576*f1fbf3c2SXin Liavailable unless the array dimension is one.
1577*f1fbf3c2SXin Li
1578*f1fbf3c2SXin Li<p><li>Inner classes or anonymous classes are not supported.
1579*f1fbf3c2SXin LiNote that this is a limitation of the compiler only.
1580*f1fbf3c2SXin LiIt cannot compile source code including an anonymous-class declaration.
1581*f1fbf3c2SXin LiJavassist can read and modify a class file of inner/anonymous class.
1582*f1fbf3c2SXin Li
1583*f1fbf3c2SXin Li<p><li>Labeled <code>continue</code> and <code>break</code> statements
1584*f1fbf3c2SXin Liare not supported.
1585*f1fbf3c2SXin Li
1586*f1fbf3c2SXin Li<p><li>The compiler does not correctly implement the Java method dispatch
1587*f1fbf3c2SXin Lialgorithm.  The compiler may confuse if methods defined in a class
1588*f1fbf3c2SXin Lihave the same name but take different parameter lists.
1589*f1fbf3c2SXin Li
1590*f1fbf3c2SXin Li<p>For example,
1591*f1fbf3c2SXin Li
1592*f1fbf3c2SXin Li<ul><pre>
1593*f1fbf3c2SXin Liclass A {}
1594*f1fbf3c2SXin Liclass B extends A {}
1595*f1fbf3c2SXin Liclass C extends B {}
1596*f1fbf3c2SXin Li
1597*f1fbf3c2SXin Liclass X {
1598*f1fbf3c2SXin Li    void foo(A a) { .. }
1599*f1fbf3c2SXin Li    void foo(B b) { .. }
1600*f1fbf3c2SXin Li}
1601*f1fbf3c2SXin Li</pre></ul>
1602*f1fbf3c2SXin Li
1603*f1fbf3c2SXin Li<p>If the compiled expression is <code>x.foo(new C())</code>, where
1604*f1fbf3c2SXin Li<code>x</code> is an instance of X, the compiler may produce a call
1605*f1fbf3c2SXin Lito <code>foo(A)</code> although the compiler can correctly compile
1606*f1fbf3c2SXin Li<code>foo((B)new C())</code>.
1607*f1fbf3c2SXin Li
1608*f1fbf3c2SXin Li<p><li>The users are recommended to use <code>#</code> as the separator
1609*f1fbf3c2SXin Libetween a class name and a static method or field name.
1610*f1fbf3c2SXin LiFor example, in regular Java,
1611*f1fbf3c2SXin Li
1612*f1fbf3c2SXin Li<ul><pre>javassist.CtClass.intType.getName()</pre></ul>
1613*f1fbf3c2SXin Li
1614*f1fbf3c2SXin Li<p>calls a method <code>getName()</code> on
1615*f1fbf3c2SXin Lithe object indicated by the static field <code>intType</code>
1616*f1fbf3c2SXin Liin <code>javassist.CtClass</code>.  In Javassist, the users can
1617*f1fbf3c2SXin Liwrite the expression shown above but they are recommended to
1618*f1fbf3c2SXin Liwrite:
1619*f1fbf3c2SXin Li
1620*f1fbf3c2SXin Li<ul><pre>javassist.CtClass#intType.getName()</pre></ul>
1621*f1fbf3c2SXin Li
1622*f1fbf3c2SXin Li<p>so that the compiler can quickly parse the expression.
1623*f1fbf3c2SXin Li</ul>
1624*f1fbf3c2SXin Li
1625*f1fbf3c2SXin Li<p><br>
1626*f1fbf3c2SXin Li
1627*f1fbf3c2SXin Li<a href="tutorial.html">Previous page</a>
1628*f1fbf3c2SXin Li&nbsp;&nbsp;&nbsp;<a href="tutorial3.html">Next page</a>
1629*f1fbf3c2SXin Li
1630*f1fbf3c2SXin Li<hr>
1631*f1fbf3c2SXin LiJava(TM) is a trademark of Sun Microsystems, Inc.<br>
1632*f1fbf3c2SXin LiCopyright (C) 2000-2015 by Shigeru Chiba, All rights reserved.
1633*f1fbf3c2SXin Li</body>
1634*f1fbf3c2SXin Li</html>
1635