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>    Local variables are not accessible.   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>, ...    </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> </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>, ...    </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> </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> </td></tr> 732*f1fbf3c2SXin Li 733*f1fbf3c2SXin Li<tr><td> </td></tr> 734*f1fbf3c2SXin Li 735*f1fbf3c2SXin Li<tr> 736*f1fbf3c2SXin Li<td><code>$1</code>, <code>$2</code>, ...    </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>    </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>    </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>    </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>    </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>, ...    </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>    </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>    </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>    </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> </td></tr> 885*f1fbf3c2SXin Li 886*f1fbf3c2SXin Li<tr><td> </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> </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> </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> </td></tr> 918*f1fbf3c2SXin Li 919*f1fbf3c2SXin Li<tr><td><code>$class</code>    </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>    </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>, ...    </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> </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>    </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>    </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>    </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>, ...    </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> </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>    </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>    </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>    </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> </td></tr> 1165*f1fbf3c2SXin Li<tr><td> </td></tr> 1166*f1fbf3c2SXin Li<tr><td> </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> </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>    </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> </td></tr> 1242*f1fbf3c2SXin Li 1243*f1fbf3c2SXin Li<tr><td> </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>    </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> </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 <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