diff options
author | patriot1burke <patriot1burke@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2003-04-22 13:47:06 +0000 |
---|---|---|
committer | patriot1burke <patriot1burke@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2003-04-22 13:47:06 +0000 |
commit | 069bceaf72fd0d6ffad14ce4e3e00ca91a280bde (patch) | |
tree | b8230a15d3061c64d5a64bf9efa654d0d6311ff2 /tutorial | |
parent | f610083ba0adbcb3fe92a504015fb26fb5a42530 (diff) | |
download | javassist-069bceaf72fd0d6ffad14ce4e3e00ca91a280bde.tar.gz javassist-069bceaf72fd0d6ffad14ce4e3e00ca91a280bde.zip |
This commit was generated by cvs2svn to compensate for changes in r2, which
included commits to RCS files with non-trunk default branches.
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@6 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'tutorial')
-rw-r--r-- | tutorial/brown.css | 19 | ||||
-rw-r--r-- | tutorial/overview.gif | bin | 0 -> 2031 bytes | |||
-rw-r--r-- | tutorial/sequence.gif | bin | 0 -> 3960 bytes | |||
-rw-r--r-- | tutorial/tutorial.html | 560 | ||||
-rw-r--r-- | tutorial/tutorial2.html | 1069 | ||||
-rw-r--r-- | tutorial/two.gif | bin | 0 -> 2502 bytes |
6 files changed, 1648 insertions, 0 deletions
diff --git a/tutorial/brown.css b/tutorial/brown.css new file mode 100644 index 00000000..b88ddb46 --- /dev/null +++ b/tutorial/brown.css @@ -0,0 +1,19 @@ +h1,h2,h3 {
+ color:#663300;
+ padding:4px 6px 6px 10px;
+ border-width:1px 0px 1px 0px;
+ border-color:#F5DEB3;
+ border-style:solid;
+}
+
+h3 {
+ padding-left: 30px;
+}
+
+h4 {
+ color:#663300;
+}
+
+em {
+ color:#cc0000;
+}
diff --git a/tutorial/overview.gif b/tutorial/overview.gif Binary files differnew file mode 100644 index 00000000..953c59a6 --- /dev/null +++ b/tutorial/overview.gif diff --git a/tutorial/sequence.gif b/tutorial/sequence.gif Binary files differnew file mode 100644 index 00000000..a59d66fd --- /dev/null +++ b/tutorial/sequence.gif diff --git a/tutorial/tutorial.html b/tutorial/tutorial.html new file mode 100644 index 00000000..3fac03ee --- /dev/null +++ b/tutorial/tutorial.html @@ -0,0 +1,560 @@ +<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Javassist Tutorial</title>
+ <link rel="stylesheet" type="text/css" href="brown.css">
+</head>
+<body>
+
+<b>
+<font size="+3">
+Getting Started with Javassist
+</font>
+
+<p><font size="+2">
+Shigeru Chiba
+</font>
+</b>
+
+<p><div align="right"><a href="tutorial2.html">Next page</a></div>
+
+<ul>1. <a href="#read">Reading bytecode</a>
+<br>2. <a href="#def">Defining a new class</a>
+<br>3. <a href="#mod">Modifying a class at load time</a>
+<br>4. <a href="#load">Class loader</a>
+<br>5. <a href="tutorial2.html#intro">Introspection and customization</a>
+</ul>
+
+<p><br>
+
+<a name="read">
+<h2>1. Reading bytecode</h2>
+
+<p>Javassist is a class library for dealing with Java bytecode.
+Java bytecode is stored in a binary file called a class file.
+Each class file contains one Java class or interface.
+
+<p>The class <code>Javassist.CtClass</code> is an abstract representation
+of a class file. A <code>CtClass</code> object is a handle for dealing
+with a class file. The following program is a very simple example:
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.get("test.Rectangle");
+cc.setSuperclass(pool.get("test.Point"));
+pool.writeFile("test.Rectangle"); // or simply, cc.writeFile()
+</pre></ul>
+
+<p>This program first obtains a <code>ClassPool</code> object,
+which controls bytecode modification with Javassist.
+The <code>ClassPool</code> object is a container of <code>CtClass</code>
+object representing a class file.
+It reads a class file on demand for constructing a <code>CtClass</code>
+object and contains the constructed object until it is written out
+to a file or an output stream.
+
+<p>To modify the definition of a class, the users must first obtain a
+reference to the <code>CtClass</code> object representing that class.
+<code>ClassPool.get()</code> is used for this purpose.
+In the case of the program above, the <code>CtClass</code> object
+representing a class <code>test.Rectangle</code> is obtained from
+the <code>ClassPool</code> object
+and it is assigned
+to a variable <code>cc</code>. Then it is modified so that
+the superclass of <code>test.Rectangle</code> is changed into
+a class <code>test.Point</code>.
+This change is reflected on the original class file when
+<code>ClassPool.writeFile()</code> is finally called.
+
+<p>Note that <code>writeFile()</code> is a method declared in not
+<code>CtClass</code> but <code>ClassPool</code>.
+If this method is called, the <code>ClassPool</code>
+finds a <code>CtClass</code> object specified with a class name
+among the objects that the <code>ClassPool</code> contains.
+Then it translates that <code>CtClass</code> object into a class file
+and writes it on a local disk.
+
+<p>There is also <code>writeFile()</code> defined in <code>CtClass</code>.
+Thus, the last line in the program above can be rewritten into:
+
+<ul><pre>cc.writeFile();</pre></ul>
+
+<p>This method is a convenient method for invoking <code>writeFile()</code>
+in <code>ClassPool</code> with the name of the class represented by
+<code>cc</code>.
+
+<p>Javassist also provides a method for directly obtaining the
+modified bytecode. To do this, call <code>write()</code>:
+
+<ul><pre>
+byte[] b = pool.write("test.Rectangle");
+</pre></ul>
+
+<p>The contents of the class file for <code>test.Rectangle</code> are
+assigned to a variable <code>b</code> in the form of byte array.
+<code>writeFile()</code> also internally calls <code>write()</code>
+to obtain the byte array written in a class file.
+
+<p>The default <code>ClassPool</code> returned
+by a static method <code>ClassPool.getDefault()</code>
+searches the same path as the underlying JVM.
+The users can expand this class search path if needed.
+For example, the following code adds a directory
+<code>/usr/local/javalib</code>
+to the search path:
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+pool.insertClassPath("/usr/local/javalib");
+</pre></ul>
+
+<p>The search path that the users can add is not only a directory but also
+a URL:
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+ClassPath cp = new URLClassPath("www.foo.com", 80, "/java/", "com.foo.");
+pool.insertClassPath(cp);
+</pre></ul>
+
+<p>This program adds "http://www.foo.com:80/java/" to the class search
+path. This URL is used only for searching classes belonging to a
+package <code>com.foo</code>.
+
+<p>You can directly give a byte array to a <code>ClassPool</code> object
+and construct a <code>CtClass</code> object from that array. To do this,
+use <code>ByteArrayClassPath</code>. For example,
+
+<ul><pre>
+ClassPool cp = ClassPool.getDefault();
+byte[] b = <em>a byte array</em>;
+String name = <em>class name</em>;
+cp.insertClassPath(new ByteArrayClassPath(name, b));
+CtClass cc = cp.get(name);
+</pre></ul>
+
+<p>The obtained <code>CtClass</code> object represents
+a class defined by the class file specified by <code>b</code>.
+
+
+<p>Since <code>ClassPath</code> is an interface, the users can define
+a new class implementing this interface and they can add an instance
+of that class so that a class file is obtained from a non-standard resource.
+
+<p><br>
+
+<a name="def">
+<h2>2. Defining a new class</h2>
+
+<p>To define a new class from scratch, <code>makeClass()</code>
+must be called on a <code>ClassPool</code>.
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.makeClass("Point");
+</pre></ul>
+
+<p>This program defines a class <code>Point</code>
+including no members.
+
+<p>A new class can be also defined as a copy of an existing class.
+The program below does that:
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.makeClass("Point");
+cc.setName("Pair");
+</pre></ul>
+
+<p>This program first obtains the <code>CtClass</code> object
+for class <code>Point</code>. Then it gives a new name <code>Pair</code>
+to that <code>CtClass</code> object.
+If <code>get("Point")</code> is called on the <code>ClassPool</code>
+object, then a class file <code>Point.class</code> is read again and
+a new <code>CtClass</code> object for class <code>Point</code> is constructed
+again.
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.makeClass("Point");
+CtClass cc1 = pool.get("Point"); // cc1 is identical to cc.
+cc.setName("Pair");
+CtClass cc2 = pool.get("Pair"); // cc2 is identical to cc.
+CtClass cc3 = pool.get("Point"); // cc3 is not identical to cc.
+</pre></ul>
+
+<p><br>
+
+<a name="mod">
+<h2>3. Modifying a class at load time</h2>
+
+<p>If what classes are modified is known in advance,
+the easiest way for modifying the classes is as follows:
+
+<ul><li>1. Get a <code>CtClass</code> object by calling
+ <code>ClassPool.get()</code>,
+ <li>2. Modify it, and
+ <li>3. Call <code>ClassPool.write()</code> or <code>writeFile()</code>.
+</ul>
+
+<p>If whether a class is modified or not is determined at load time,
+the users can write an event listener so that it is notified
+when a class is loaded into the JVM.
+A class loader (<code>java.lang.ClassLoader</code>) working with
+Javassist must call <code>ClassPool.write()</code> for obtaining
+a class file. The users can write an event listener so that it is
+notified when the class loader calls <code>ClassPool.write()</code>.
+The event-listener class must implement the following interface:
+
+<ul><pre>public interface Translator {
+ public void start(ClassPool pool)
+ throws NotFoundException, CannotCompileException;
+ public void onWrite(ClassPool pool, String classname)
+ throws NotFoundException, CannotCompileException;
+}</pre></ul>
+
+<p>The method <code>start()</code> is called when this event listener
+is registered to a <code>ClassPool</code> object.
+The method <code>onWrite()</code> is called when <code>write()</code>
+(or similar methods) is called on the <code>ClassPool</code> object.
+The second parameter of <code>onWrite()</code> is the name of the class
+to be written out.
+
+<p>Note that <code>start()</code> or <code>onWrite()</code> do not have
+to call <code>write()</code> or <code>writeFile()</code>. For example,
+
+<ul><pre>public class MyAnotherTranslator implements Translator {
+ public void start(ClassPool pool)
+ throws NotFoundException, CannotCompileException {}
+ public void onWrite(ClassPool pool, String classname)
+ throws NotFoundException, CannotCompileException
+ {
+ CtClass cc = pool.get(classname);
+ cc.setModifiers(Modifier.PUBLIC);
+ }
+}</pre></ul>
+
+<p>All the classes written out by <code>write()</code> are made public
+just before their definitions are translated into an byte array.
+
+<p><center><img src="overview.gif" alt="overview"></center>
+
+<p>The two methods <code>start()</code> and <code>onWrite()</code>
+can modify not only a <code>CtClass</code> object specified by
+the given <code>classname</code> but also
+<em>any</em> <code>CtClass</code> objects contained
+in the given <code>ClassPool</code>.
+They can call <code>ClassPool.get()</code> for obtaining any
+<code>CtClass</code> object.
+If a modified <code>CtClass</code> object is not written out immediately,
+the modification is recorded until that object is written out.
+
+<p><center><img src="sequence.gif" alt="sequence diagram"></center>
+
+<p>To register an event listener to a <code>ClassPool</code>,
+it must be passed to a constructor of <code>ClassPool</code>.
+Only a single event listener can be registered.
+If more than one event listeners are needed, multiple
+<code>ClassPool</code>s should be connected to be a single
+stream. For example,
+
+<ul><pre>Translator t1 = new MyTranslator();
+ClassPool c1 = new ClassPool(t1);
+Translator t2 = new MyAnotherTranslator();
+ClassPool c2 = new ClassPool(c1, t2);</pre></ul>
+
+<p>This program connects two <code>ClassPool</code>s.
+If a class loader calls <code>write()</code> on <code>c2</code>,
+the specified class file is first modified by <code>t1</code> and
+then by <code>t2</code>. <code>write()</code> returns the resulting
+class file.
+
+First, <code>onWrite()</code> on <code>t1</code> is called since
+<code>c2</code> obtains a class file by calling <code>write()</code>
+on <code>c1</code>. Then <code>onWrite()</code> on <code>t2</code>
+is called. If <code>onWrite()</code> called on <code>t2</code>
+obtains a <code>CtClass</code> object from <code>c2</code>, that
+<code>CtClass</code> object represents the class file that
+<code>t1</code> has modified.
+
+<p><center><img src="two.gif" alt="two translators"></center>
+
+<p><br>
+
+<a name="load">
+<h2>4. Class loader</h2>
+
+<p>Javassist can be used with a class loader so that bytecode can be
+modified at load time. The users of Javassist can define their own
+version of class loader but they can also use a class loader provided
+by Javassist.
+
+<p><br>
+
+<h3>4.1 Using <code>javassist.Loader</code></h3>
+
+<p>Javassist provides a class loader
+<code>javassist.Loader</code>. This class loader uses a
+<code>javassist.ClassPool</code> object for reading a class file.
+
+<p>For example, <code>javassist.Loader</code> can be used for loading
+a particular class modified with Javassist.
+
+<ul><pre>
+import javassist.*;
+import test.Rectangle;
+
+public class Main {
+ public static void main(String[] args) throws Throwable {
+ ClassPool pool = ClassPool.getDefault();
+ Loader cl = new Loader(pool);
+
+ CtClass ct = pool.get("test.Rectangle");
+ ct.setSuperclass(pool.get("test.Point"));
+
+ Class c = cl.loadClass("test.Rectangle");
+ Object rect = c.newInstance();
+ :
+ }
+}
+</pre></ul>
+
+<p>This program modifies a class <code>test.Rectangle</code>. The
+superclass of <code>test.Rectangle</code> is set to a
+<code>test.Point</code> class. Then this program loads the modified
+class into the JVM, and creates a new instance of the
+<code>test.Rectangle</code> class.
+
+<p>The users can use a <code>javassist.Translator</code> object
+for modifying class files.
+Suppose that an instance of a class <code>MyTranslator</code>,
+which implements
+<code>javassist.Translator</code>, performs modification of class files.
+To run an application class <code>MyApp</code> with the
+<code>MyTranslator</code> object, write a main class:
+
+<ul><pre>
+import javassist.*;
+
+public class Main2 {
+ public static void main(String[] args) throws Throwable {
+ Translator t = new MyTranslator();
+ ClassPool pool = ClassPool.getDefault(t);
+ Loader cl = new Loader(pool);
+ cl.run("MyApp", args);
+ }
+}
+</pre></ul>
+
+<p>To run this program, do:
+
+<ul><pre>
+% java Main <i>arg1</i> <i>arg2</i>...
+</pre></ul>
+
+<p>The class <code>MyApp</code> and the other application classes
+are translated by <code>MyTranslator</code>.
+
+<p>Note that <em>application</em> classes like <code>MyApp</code> cannot
+access the <em>loader</em> classes such as <code>Main</code>,
+<code>MyTranslator</code> and <code>ClassPool</code> because they
+are loaded by different loaders. The application classes are loaded
+by <code>javassist.Loader</code> whereas the loader classes such as
+<code>Main</code> are by the default Java class loader.
+
+<p>In Java, for security reasons, a single class file may be loaded
+into the JVM by two distinct class loaders so that two different
+classes would be created. For example,
+
+<ul><pre>class Point {
+ int x, y;
+}
+
+class Box {
+ Point base;
+ Point getBase() { return base; }
+}
+
+class Window {
+ Point size;
+ Point getSize() { return size; }
+}</pre></ul>
+
+<p>Suppose that a class <code>Box</code> is loaded by a class loader
+<code>L1</code> while a class <code>Window</code> is loaded by a class
+loader <code>L2</code>. Then, the obejcts returned by
+<code>getBase()</code> and <code>getSize()</code> are not instances of
+the same class <code>Point</code>.
+<code>getBase()</code> returns an instance of the class <code>Point</code>
+loaded by <code>L1</code> whereas <code>getSize()</code> returns an
+instance of <code>Point</code> loaded by <code>L2</code>. The two versions
+of the class <code>Point</code> are distinct. They belong to different
+name spaces. For more details, see the following paper:
+
+<ul>Sheng Liang and Gilad Bracha,
+"Dynamic Class Loading in the Java Virtual Machine",
+<br><i>ACM OOPSLA'98</i>, pp.36-44, 1998.</ul>
+
+<p>To avoid this problem, the two class loaders <code>L1</code> and
+<code>L2</code> must delegate the loading operation of the class
+<code>Point</code> to another class loader, <code>L3</code>, which is
+a parent class loader of <code>L1</code> and <code>L2</code>.
+<code>delegateLoadingOf()</code> in <code>javassist.Loader</code>
+is a method for specifying what classes should be loaded by the
+parent loader.
+
+<p>If <code>L1</code> is the parent class loader of <code>L2</code>,
+that is, if <code>L1</code> loads the class of <code>L2</code>,
+then <code>L2</code> can delegate the loading operation of
+<code>Point</code> to <code>L1</code> for avoiding the problem above.
+However, this technique does not work in the case below:
+
+<ul><pre>class Point { // loaded by L1
+ Window win;
+ int x, y;
+}
+
+class Box { // loaded by L1
+ Point base;
+ Point getBase() { return base; }
+}
+
+class Window { // loaded by L2
+ Point size;
+ Point getSize() { size.win = this; return size; }
+}</pre></ul>
+
+<p>Since all the classes included in a class definition loaded by
+a class loader <code>L1</code> are also loaded by <code>L1</code>,
+the class of the field <code>win</code> in <code>Point</code> is
+now the class <code>Window</code> loaded by <code>L1</code>.
+Thus <code>size.win = this</code> in <code>getSize()</code> raises
+a runtime exception because of type mismatch; the type of
+<code>size.win</code> is the class <code>Point</code> loaded by
+<code>L1</code> whereas the type of <code>this</code> is the class
+<code>Point</code> loaded by <code>L2</code>.
+
+<p><br>
+
+<h3>4.2 Writing a class loader</h3>
+
+<p>A simple class loader using Javassist is as follows:
+
+<ul><pre>import javassist.*;
+
+public class SimpleLoader extends ClassLoader {
+ /* Call MyApp.main().
+ */
+ public static void main(String[] args) throws Throwable {
+ SimpleLoader s = new SimpleLoader();
+ Class c = s.loadClass("MyApp");
+ c.getDeclaredMethod("main", new Class[] { String[].class })
+ .invoke(null, new Object[] { args });
+ }
+
+ private ClassPool pool;
+
+ public SimpleLoader() throws NotFoundException {
+ pool = ClassPool.getDefault();
+ pool.insertClassPath("./class"); // <em>MyApp.class must be there.</em>
+ }
+
+ /* Finds a specified class.
+ * The bytecode for that class can be modified.
+ */
+ protected Class findClass(String name) throws ClassNotFoundException {
+ try {
+ CtClass cc = pool.get(name);
+ // <em>modify the CtClass object here</em>
+ byte[] b = pool.write(name);
+ return defineClass(name, b, 0, b.length);
+ } catch (NotFoundException e) {
+ throw new ClassNotFoundException();
+ } catch (IOException e) {
+ throw new ClassNotFoundException();
+ } catch (CannotCompileException e) {
+ throw new ClassNotFoundException();
+ }
+ }
+}</pre></ul>
+
+<p>The class <code>MyApp</code> is an application program.
+To execute this program, first put the class file under the
+<code>./class</code> directory, which must <em>not</em> be included
+in the class search path. The directory name is specified by
+<code>insertClassPath()</code> in the constructor.
+You can choose a different name instead of <code>./class</code> if you want.
+Then do as follows:
+
+<ul><code>% java SimpleLoader</code></ul>
+
+<p>The class loader loads the class <code>MyApp</code>
+(<code>./class/MyApp.class</code>) and calls
+<code>MyApp.main()</code> with the command line parameters.
+Note that <code>MyApp.class</code> must not be under the directory
+that the system class loader searches. Otherwise, the system class
+loader, which is the parent loader of <code>SimpleLoader</code>,
+loads the class <code>MyApp</code>.
+
+<p>This is the simplest way of using Javassist. However, if you write
+a more complex class loader, you may need detailed knowledge of
+Java's class loading mechanism. For example, the program above puts the
+<code>MyApp</code> class in a name space separated from the name space
+that the class <code>SimpleLoader</code> belongs to because the two
+classes are loaded by different class loaders.
+Hence, the
+<code>MyApp</code> class cannot directly access the class
+<code>SimpleLoader</code>.
+
+<p><br>
+
+<h3>4.3 Modifying a system class</h3>
+
+<p>The system classes like <code>java.lang.String</code> cannot be
+loaded by a class loader other than the system class loader.
+Therefore, <code>SimpleLoader</code> or <code>javassist.Loader</code>
+shown above cannot modify the system classes at loading time.
+
+<p>If your application needs to do that, the system classes must be
+<em>statically</em> modified. For example, the following program
+adds a new field <code>hiddenValue</code> to <code>java.lang.String</code>:
+
+<ul><pre>ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.get("java.lang.String");
+cc.addField(new CtField(CtClass.intType, "hiddenValue", cc));
+pool.writeFile("java.lang.String", ".");</pre></ul>
+
+<p>This program produces a file <code>"./java/lang/String.class"</code>.
+
+<p>To run your program <code>MyApp</code>
+with this modified <code>String</code> class, do as follows:
+
+<ul><pre>
+% java -Xbootclasspath/p:. MyApp <i>arg1</i> <i>arg2</i>...
+</pre></ul>
+
+<p>Suppose that the definition of <code>MyApp</code> is as follows:
+
+<ul><pre>public class MyApp {
+ public static void main(String[] args) throws Exception {
+ System.out.println(String.class.getField("hiddenValue").getName());
+ }
+}</pre></ul>
+
+<p>If the modified <code>String</code> class is correctly loaded,
+<code>MyApp</code> prints <code>hiddenValue</code>.
+
+<p><i>Note: Applications that use this technique for the purpose of
+overriding a system class in <code>rt.jar</code> should not be
+deployed as doing so would contravene the Java 2 Runtime Environment
+binary code license.</i>
+
+<p><br>
+
+<a href="tutorial2.html">Next page</a>
+
+<hr>
+Java(TM) is a trademark of Sun Microsystems, Inc.<br>
+Copyright (C) 2000-2002 by Shigeru Chiba, All rights reserved.
+</body>
+</html>
diff --git a/tutorial/tutorial2.html b/tutorial/tutorial2.html new file mode 100644 index 00000000..b76996ce --- /dev/null +++ b/tutorial/tutorial2.html @@ -0,0 +1,1069 @@ +<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Javassist Tutorial</title>
+ <link rel="stylesheet" type="text/css" href="brown.css">
+</head>
+
+<body>
+
+<div align="right">Getting Started with Javassist</div>
+
+<div align="left"><a href="tutorial.html">Previous page</a></div>
+
+<a name="intro">
+<h2>5. Introspection and customization</h2>
+
+<p><code>CtClass</code> provides methods for introspection. The
+introspective ability of Javassist is compatible with that of
+the Java reflection API. <code>CtClass</code> provides
+<code>getName()</code>, <code>getSuperclass()</code>,
+<code>getMethods()</code>, and so on.
+<code>CtClass</code> also provides methods for modifying a class
+definition. It allows to add a new field, constructor, and method.
+Instrumenting a method body is also possible.
+
+<p><hr width="40%">
+
+<ul>
+Javassist does not allow to remove a method or field, but it allows
+to change the name. So if a method is not necessary any more, it should be
+renamed and changed to be a private method by calling
+<code>setName()</code>
+and <code>setModifiers()</code> declared in <code>CtMethod</code>.
+
+<p>Javassist does not allow to add an extra parameter to an existing
+method, either. Instead of doing that, a new method receiving the
+extra parameter as well as the other parameters should be added to the
+same class. For example, if you want to add an extra <code>int</code>
+parameter <code>newZ</code> to a method:
+
+<ul><pre>void move(int newX, int newY) { x = newX; y = newY; }</pre></ul>
+
+<p>in a <code>Point</code> class, then you should add the following
+method to the <code>Point</code> class:
+
+<ul><pre>void move(int newX, int newY, int newZ) {
+ // do what you want with newZ.
+ move(newX, newY);
+}</pre></ul>
+
+</ul>
+
+<p><hr width="40%">
+
+<p>Javassist also provides low-level API for directly editing a raw
+class file. For example, <code>getClassFile()</code> in
+<code>CtClass</code> returns a <code>ClassFile</code> object
+representing a raw class file. <code>getMethodInfo()</code> in
+<code>CtMethod</code> returns a <code>MethodInfo</code> object
+representing a <code>method_info</code> structure included in a class
+file. The low-level API uses the vocabulary from the Java Virtual
+machine specification. The users must have the knowledge about class
+files and bytecode. For more details, the users should see the
+<code>javassist.bytecode</code> package.
+
+<p><br>
+
+<h3>5.1 Inserting source text at the beginning/end of a method body</h3>
+
+<p><code>CtMethod</code> and <code>CtConstructor</code> provide
+methods <code>insertBefore()</code>, <code>insertAfter()</code>, and
+<code>addCatch()</code>. They are used for inserting a code fragment
+into the body of an existing method. The users can specify those code
+fragments with <em>source text</em> written in Java.
+Javassist includes a simple Java compiler for processing source
+text. It receives source text
+written in Java and compiles it into Java bytecode, which will be inserted
+into a method body.
+
+<p>The methods <code>insertBefore()</code>, <code>insertAfter()</code>, and
+<code>addCatch()</code> receives a <code>String</code> object representing
+a statement or a block. A statement is a single control structure like
+<code>if</code> and <code>while</code> or an expression ending with
+a semi colon (<code>;</code>). A block is a set of
+statements surrounded with braces <code>{}</code>.
+Hence each of the following lines is an example of valid statement or block:
+
+<ul><pre>System.out.println("Hello");
+{ System.out.println("Hello"); }
+if (i < 0) { i = -i; }
+</pre></ul>
+
+<p>The statement and the block can refer to fields and methods.
+However, they <em>cannot refer to local variables</em> declared in the
+method that they are inserted into.
+They can refer to the parameters
+to the method although they must use different names
+<code>$0</code>, <code>$1</code>, <code>$2</code>, ... described
+below. Declaring a local variable in the block is allowed.
+
+<!--
+<p><center><table border=8 cellspacing=0 bordercolor="#cfcfcf">
+<tr><td bgcolor="#cfcfcf">
+<b>Tip:</b>
+<br>    Local variables are not accessible.  
+</td></tr>
+</table></center>
+-->
+
+<p>The <code>String</code> object passed to the methods
+<code>insertBefore()</code>, <code>insertAfter()</code>, and
+<code>addCatch()</code> are compiled by
+the compiler included in Javassist.
+Since the compiler supports language extensions,
+several identifiers starting with <code>$</code>
+have special meaning:
+
+<ul><table border=0>
+<tr>
+<td><code>$0</code>, <code>$1</code>, <code>$2</code>, ...    </td>
+<td>Actual parameters</td>
+</tr>
+
+<tr>
+<td><code>$args</code></td>
+<td>An array of parameters.
+The type of <code>$args</code> is <code>Object[]</code>.
+</td>
+</tr>
+
+<tr>
+<td><code>$$</code></td>
+<td rowspan=2>All actual parameters.<br>
+For example, <code>m($$)</code> is equivalent to
+<code>m($1,$2,</code>...<code>)</code></td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr>
+<td><code>$cflow(</code>...<code>)</code></td>
+<td><code>cflow</code> variable</td>
+</tr>
+
+<tr>
+<td><code>$r</code></td>
+<td>The result type. It is used in a cast expression.</td>
+</tr>
+
+<tr>
+<td><code>$w</code></td>
+<td>The wrapper type. It is used in a cast expression.</td>
+</tr>
+
+<tr>
+<td><code>$_</code></td>
+<td>The resulting value</td>
+</tr>
+
+<tr>
+<td><code>$sig</code></td>
+<td>An array of <code>java.lang.Class</code> objects representing
+the formal parameter types.
+</td>
+</tr>
+
+<tr>
+<td><code>$type</code></td>
+<td>A <code>java.lang.Class</code> object representing
+the formal result type.</td>
+</tr>
+
+<tr>
+<td><code>$class</code></td>
+<td>A <code>java.lang.Class</code> object representing
+the class currently edited.</td>
+</tr>
+
+</table>
+</ul>
+
+<h4>$0, $1, $2, ...</h4>
+
+<p>The parameters passed to the methods <code>insertBefore()</code>,
+<code>insertAfter()</code>, and <code>addCatch()</code>
+are accessible with
+<code>$0</code>, <code>$1</code>, <code>$2</code>, ... instead of
+the original parameter names.
+<code>$1</code> represents the
+first parameter, <code>$2</code> represents the second parameter, and
+so on. The types of those variables are identical to the parameter
+types.
+<code>$0</code> is
+equivalent to <code>this</code>. If the method is static,
+<code>$0</code> is not available.
+
+<p>These variables are used as following. Suppose that a class
+<code>Point</code>:
+
+<pre><ul>class Point {
+ int x, y;
+ void move(int dx, int dy) { x += dx; y += dy; }
+}
+</ul></pre>
+
+<p>To print the values of <code>dx</code> and <code>dy</code>
+whenever the method <code>move()</code> is called, execute this
+program:
+
+<ul><pre>ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.get("Point");
+CtMethod m = cc.getDeclaredMethod("move");
+m.insertBefore("{ System.out.println($1); System.out.println($2); }");
+cc.writeFile();
+</pre></ul>
+
+<p>Note that the source text passed to <code>insertBefore()</code> is
+surrounded with braces <code>{}</code>.
+<code>insertBefore()</code> accepts only a single statement or a block
+surrounded with braces.
+
+<p>The definition of the class <code>Point</code> after the
+modification is like this:
+
+<pre><ul>class Point {
+ int x, y;
+ void move(int dx, int dy) {
+ { System.out.println(dx); System.out.println(dy); }
+ x += dx; y += dy;
+ }
+}
+</ul></pre>
+
+<p><code>$1</code> and <code>$2</code> are replaced with
+<code>dx</code> and <code>dy</code>, respectively.
+
+<p><code>$1</code>, <code>$2</code>, <code>$3</code> ... are
+updatable. If a new value is assigend to one of those variables,
+then the value of the parameter represented by that variable is
+also updated.
+
+
+<h4>$args</h4>
+
+<p>The variable <code>$args</code> represents an array of all the
+parameters. The type of that variable is an array of class
+<code>Object</code>. If a parameter type is a primitive type such as
+<code>int</code>, then the parameter value is converted into a wrapper
+object such as <code>java.lang.Integer</code> to store in
+<code>$args</code>. Thus, <code>$args[0]</code> is equivalent to
+<code>$1</code> unless the type of the first parameter is a primitive
+type. Note that <code>$args[0]</code> is not equivalent to
+<code>$0</code>; <code>$0</code> represents <code>this</code>.
+
+<p>If an array of <code>Object</code> is assigned to
+<code>$args</code>, then each element of that array is
+assigned to each parameter. If a parameter type is a primitive
+type, the type of the corresponding element must be a wrapper type.
+The value is converted from the wrapper type to the primitive type
+before it is assigned to the parameter.
+
+<h4>$$</h4>
+
+<p>The variable <code>$$</code> is abbreviation of a list of
+all the parameters separated by commas.
+For example, if the number of the parameters
+to method <code>move()</code> is three, then
+
+<ul><pre>move($$)</pre></ul>
+
+<p>is equivalent to this:
+
+<ul><pre>move($1, $2, $3)</pre></ul>
+
+<p>If <code>move()</code> does not take any parameters,
+then <code>move($$)</code> is
+equivalent to <code>move()</code>.
+
+<p><code>$$</code> can be used with another method.
+If you write an expression:
+
+<ul><pre>exMove($$, context)</pre></ul>
+
+<p>then this expression is equivalent to:
+
+<ul><pre>exMove($1, $2, $3, context)</pre></ul>
+
+<p>Note that <code>$$</code> enables generic notation of method call
+with respect to the number of parameters.
+It is typically used with <code>$proceed</code> shown later.
+
+<h4>$cflow</h4>
+
+<p><code>$cflow</code> means "control flow".
+This read-only variable returns the depth of the recursive calls
+to a specific method.
+
+<p>Suppose that the method shown below is represented by a
+<code>CtMethod</code> object <code>cm</code>:
+
+<ul><pre>int fact(int n) {
+ if (n <= 1)
+ return n;
+ else
+ return n * fact(n - 1);
+}</pre></ul>
+
+<p>To use <code>$cflow</code>, first declare that <code>$cflow</code>
+is used for monitoring calls to the method <code>fact()</code>:
+
+<ul><pre>CtMethod cm = ...;
+cm.useCflow("fact");</pre></ul>
+
+<p>The parameter to <code>useCflow()</code> is the identifier of the
+declared <code>$cflow</code> variable. Any valid Java name can be
+used as the identifier. Since the identifier can also include
+<code>.</code> (dot), for example, <code>"my.Test.fact"</code>
+is a valid identifier.
+
+<p>Then, <code>$cflow(fact)</code> represents the depth of the
+recursive calls to the method specified by <code>cm</code>. The value
+of <code>$cflow(fact)</code> is 0 (zero) when the method is
+first called whereas it is 1 when the method is recursively called
+within the method. For example,
+
+<ul><pre>
+cm.insertBefore("if ($cflow(fact) == 0)"
+ + " System.out.println(\"fact \" + $1);");
+</pre></ul>
+
+<p>translates the method <code>fact()</code> so that it shows the
+parameter. Since the value of <code>$cflow(fact)</code> is checked,
+the method <code>fact()</code> does not show the parameter if it is
+recursively called within <code>fact()</code>.
+
+<p>The value of <code>$cflow</code> is the number of stack frames
+associated with the specified method <code>cm</code>
+under the current topmost
+stack frame for the current thread. <code>$cflow</code> is also
+accessible within a method different from the specified method
+<code>cm</code>.
+
+<h4>$r</h4>
+
+<p><code>$r</code> represents the result type (return type) of the method.
+It must be used as the cast type in a cast expression.
+For example, this is a typical use:
+
+<ul><pre>Object result = ... ;
+$_ = ($r)result;</pre></ul>
+
+<p>If the result type is a primitive type, then <code>($r)</code>
+converts from the wrapper type to the primitive type.
+For example, if the result type is <code>int</code>, then
+<code>($r)</code> converts from <code>java.lang.Integer</code> to
+<code>int</code>.
+
+<p>If the result type is <code>void</code>, then
+<code>($r)</code> does not convert a type; it does nothing.
+Moreover, the soruce text can include a <code>return</code>
+statement with a resulting value:
+
+<ul><pre>return ($r)result;</pre></ul>
+
+<p>Here, <code>result</code> is some local variable.
+Since <code>($r)</code> is specified, the resulting value is
+discarded.
+This <code>return</code> statement is regarded as the equivalent
+of the <code>return</code> statement without a resulting value:
+
+<ul><pre>return;</pre></ul>
+
+<h4>$w</h4>
+
+<p><code>$w</code> represents a wrapper type.
+It must be used as the cast type in a cast expression.
+<code>($w)</code> converts from a primitive type to the corresponding
+wrapper type.
+
+The following code is an example:
+
+<ul><pre>Integer i = ($w)5;</pre></ul>
+
+<p>The selected wrapper type depends on the type of the expression
+following <code>($w)</code>. If the type of the expression is
+<code>double</code>, then the wrapper type is <code>java.lang.Double</code>.
+
+<p>If the type of the expression following <code>($w)</code> is not
+a primitive type, then <code>($w)</code> does nothing.
+
+<h4>$_</h4>
+
+<p><code>insertAfter()</code> in <code>CtMethod</code> and
+<code>CtConstructor</code> inserts the
+compiled code at the end of the method. In the statement given to
+<code>insertAfter()</code>, not only the variables shown above such as
+<code>$0</code>, <code>$1</code>, ... but also <code>$_</code> is
+available.
+
+<p>The variable <code>$_</code> represents the resulting value of the
+method. The type of that variable is the type of the result type (the
+return type) of the method. If the result type is <code>void</code>,
+then the type of <code>$_</code> is <code>Object</code> and the value
+of <code>$_</code> is <code>null</code>.
+
+<p>Although the compiled code inserted by <code>insertAfter()</code>
+is executed just before the control normally returns from the method,
+it can be also executed when an exception is thrown from the method.
+To execute it when an exception is thrown, the second parameter
+<code>asFinally</code> to <code>insertAfter()</code> must be
+<code>true</code>.
+
+<p>If an exception is thrown, the compiled code inserted by
+<code>insertAfter()</code> is executed as a <code>finally</code>
+clause. The value of <code>$_</code> is <code>0</code> or
+<code>null</code> in the compiled code. After the execution of the
+compiled code terminates, the exception originally thrown is re-thrown
+to the caller. Note that the value of <code>$_</code> is never thrown
+to the caller; it is rather discarded.
+
+<h4>$sig</h4>
+
+<p>The value of <code>$sig</code> is an array of
+<code>java.lang.Class</code> objects that represent the formal
+parameter types in declaration order.
+
+<h4>$type</h4>
+
+<p>The value of <code>$type</code> is an <code>java.lang.Class</code>
+object representing the formal type of the result value. This
+variable is available only in <code>insertAfter()</code> in
+<code>CtMethod</code> and <code>CtConstructor</code>.
+
+<h4>$class</h4>
+
+<p>The value of <code>$class</code> is an <code>java.lang.Class</code>
+object representing the class in which the edited method is declared.
+
+<h4>addCatch()</h4>
+
+<p><code>addCatch()</code> inserts a code fragment into a method body
+so that the code fragment is executed when the method body throws
+an exception and the control returns to the caller. In the source
+text representing the inserted code fragment, the exception value
+is referred to with the name specified by the third parameter to
+<code>addCatch()</code>.
+
+<p>For example, this program:
+
+<ul><pre>
+CtMethod m = ...;
+CtClass etype = ClassPool.getDefault().get("java.io.IOException");
+m.addCatch("{ System.out.println(e); throw e; }", etype, "e");
+</pre></ul>
+
+<p>translates the method body represented by <code>m</code> into
+something like this:
+
+<ul><pre>
+try {
+ <font face="serif"><em>the original method body</em></font>
+}
+catch (java.io.IOException e) {
+ System.out.println(e);
+ throw e;
+}
+</pre></ul>
+
+<p>Note that the inserted code fragment must end with a
+<code>throw</code> or <code>return</code> statement.
+
+<p><br>
+
+<h3>5.2 Modifying a method body</h3>
+
+<p><code>javassist.expr.ExprEditor</code> is a class
+for replacing an expression in a method body.
+The users can define a subclass of <code>ExprEditor</code>
+to specify how an expression is modified.
+
+<p>To run an <code>ExprEditor</code> object, the users must
+call <code>instrument()</code> in <code>CtMethod</code> or
+<code>CtClass</code>.
+
+For example,
+
+<ul><pre>
+CtMethod cm = ... ;
+cm.instrument(
+ new ExprEditor() {
+ public void edit(MethodCall m)
+ throws CannotCompileException
+ {
+ if (m.getClassName().equals("Point")
+ && m.getMethodName().equals("move"))
+ m.replace("{ $1 = 0; $_ = $proceed($$); }");
+ }
+ });
+</pre></ul>
+
+<p>searches the method body represented by <code>cm</code> and
+replaces all calls to <code>move()</code> in class <code>Point</code>
+with a block:
+
+<ul><pre>{ $1 = 0; $_ = $proceed($$); }
+</pre></ul>
+
+<p>so that the first parameter to <code>move()</code> is always 0.
+Note that the substituted code is not an expression but
+a statement or a block.
+
+<p>The method <code>instrument()</code> searches a method body.
+If it finds an expression such as a method call, field access, and object
+creation, then it calls <code>edit()</code> on the given
+<code>ExprEditor</code> object. The parameter to <code>edit()</code>
+is an object representing the found expression. The <code>edit()</code>
+method can inspect and replace the expression through that object.
+
+<p>Calling <code>replace()</code> on the parameter to <code>edit()</code>
+substitutes the given statement or block for the expression. If the given
+block is an empty block, that is, if <code>replace("{}")</code>
+is executed, then the expression is removed from the method body.
+
+If you want to insert a statement (or a block) before/after the
+expression, a block like the following should be passed to
+<code>replace()</code>:
+
+<ul><pre>
+{ <em>before-statements;</em>
+ $_ = $proceed($$);
+ <em>after-statements;</em> }
+</pre></ul>
+
+<p>whichever the expression is either a method call, field access,
+object creation, or others. The second statement could be:
+
+<ul><pre>$_ = $proceed();</pre></ul>
+
+<p>if the expression is read access, or
+
+<ul><pre>$proceed($$);</pre></ul>
+
+<p>if the expression is write access.
+
+<h4>javassist.expr.MethodCall</h4>
+
+<p>A <code>MethodCall</code> object represents a method call.
+The method <code>replace()</code> in
+<code>MethodCall</code> substitutes a statement or
+a block for the method call.
+It receives source text representing the substitued statement or
+block, in which the identifiers starting with <code>$</code>
+have special meaning as in the source text passed to
+<code>insertBefore()</code>.
+
+<ul><table border=0>
+<tr>
+<td><code>$0</code></td>
+<td rowspan=3>
+The target object of the method call.<br>
+This is not equivalent to <code>this</code>, which represents
+the caller-side <code>this</code> object.<br>
+<code>$0</code> is <code>null</code> if the method is static.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr><td> </td></tr>
+
+<tr>
+<td><code>$1</code>, <code>$2</code>, ...    </td>
+<td>
+The parameters of the method call.
+</td>
+</tr>
+
+<tr><td>
+<code>$_</code></td>
+<td>The resulting value of the method call.</td>
+</tr>
+
+<tr><td><code>$r</code></td>
+<td>The result type of the method call.</td>
+</tr>
+
+<tr><td><code>$class</code>    </td>
+<td>A <code>java.lang.Class</code> object representing
+the class declaring the method.
+</td>
+</tr>
+
+<tr><td><code>$sig</code>    </td>
+<td>An array of <code>java.lang.Class</code> objects representing
+the formal parameter types.</td>
+</tr>
+
+<tr><td><code>$type</code>    </td>
+<td>A <code>java.lang.Class</code> object representing
+the formal result type.</td>
+</tr>
+
+<tr><td><code>$proceed</code>    </td>
+<td>The name of the method originally called
+in the expression.</td>
+</tr>
+
+</table>
+</ul>
+
+<p>Here the method call means the one represented by the
+<code>MethodCall</code> object.
+
+<p>The other identifiers such as <code>$w</code>,
+<code>$args</code> and <code>$$</code>
+are also available.
+
+<p>Unless the result type of the method call is <code>void</code>,
+a value must be assigned to
+<code>$_</code> in the source text and the type of <code>$_</code>
+is the result type.
+If the result type is <code>void</code>, the type of <code>$_</code>
+is <code>Object</code> and the value assigned to <code>$_</code>
+is ignored.
+
+<p><code>$proceed</code> is not a <code>String</code> value but special
+syntax. It must be followed by an argument list surrounded by parentheses
+<code>( )</code>.
+
+<h4>javassist.expr.FieldAccess</h4>
+
+<p>A <code>FieldAccess</code> object represents field access.
+The method <code>edit()</code> in <code>ExprEditor</code>
+receive this object if field access is found.
+The method <code>replace()</code> in
+<code>FieldAccess</code> receives
+source text representing the substitued statement or
+block for the field access.
+
+In the source text, the identifiers starting with <code>$</code>
+have also special meaning:
+
+<ul><table border=0>
+<tr>
+<td><code>$0</code></td>
+<td rowspan=3>
+The object containing the field accessed by the expression.
+This is not equivalent to <code>this</code>.<br>
+<code>this</code> represents the object that the method including the
+expression is invoked on.<br>
+<code>$0</code> is <code>null</code> if the field is static.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr><td> </td></tr>
+
+<tr>
+<td><code>$1</code></td>
+<td rowspan=2>
+The value that would be stored in the field
+if the expression is write access.
+<br>Otherwise, <code>$1</code> is not available.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr>
+<td><code>$_</code></td>
+<td rowspan=2>
+The resulting value of the field access
+if the expression is read access.
+<br>Otherwise, the value stored in <code>$_</code> is discarded.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+<tr>
+<td><code>$r</code></td>
+<td rowspan=2>
+The type of the field if the expression is read access.
+<br>Otherwise, <code>$r</code> is <code>void</code>.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr><td><code>$class</code>    </td>
+<td>A <code>java.lang.Class</code> object representing
+the class declaring the field.
+</td></tr>
+
+<tr><td><code>$type</code></td>
+<td>A <code>java.lang.Class</code> object representing
+the field type.</td>
+</tr>
+
+<tr><td><code>$proceed</code>    </td>
+<td>The name of a virtual method executing the original
+field access.
+.</td>
+</tr>
+
+</table>
+</ul>
+
+<p>The other identifiers such as <code>$w</code>,
+<code>$args</code> and <code>$$</code>
+are also available.
+
+<p>If the expression is read access, a value must be assigned to
+<code>$_</code> in the source text. The type of <code>$_</code>
+is the type of the field.
+
+<h4>javassist.expr.NewExpr</h4>
+
+<p>A <code>NewExpr</code> object represents object creation
+with the <code>new</code> operator.
+The method <code>edit()</code> in <code>ExprEditor</code>
+receive this object if object creation is found.
+The method <code>replace()</code> in
+<code>NewExpr</code> receives
+source text representing the substitued statement or
+block for the object creation.
+
+In the source text, the identifiers starting with <code>$</code>
+have also special meaning:
+
+<ul><table border=0>
+
+<tr>
+<td><code>$0</code></td>
+<td>
+<code>null</code>.
+</td>
+</tr>
+
+<tr>
+<td><code>$1</code>, <code>$2</code>, ...    </td>
+<td>
+The parameters to the constructor.
+</td>
+</tr>
+
+<tr>
+<td><code>$_</code></td>
+<td rowspan=2>
+The resulting value of the object creation.
+<br>A newly created object must be stored in this variable.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr>
+<td><code>$r</code></td>
+<td>
+The type of the created object.
+</td>
+</tr>
+
+<tr><td><code>$class</code>    </td>
+<td>A <code>java.lang.Class</code> object representing
+the class of the created object.
+</td></tr>
+
+<tr><td><code>$sig</code>    </td>
+<td>An array of <code>java.lang.Class</code> objects representing
+the formal parameter types.</td>
+</tr>
+
+<tr><td><code>$proceed</code>    </td>
+<td>The name of a virtual method executing the original
+object creation.
+.</td>
+</tr>
+
+</table>
+</ul>
+
+<p>The other identifiers such as <code>$w</code>,
+<code>$args</code> and <code>$$</code>
+are also available.
+
+<h4>javassist.expr.Instanceof</h4>
+
+<p>A <code>Instanceof</code> object represents an <code>instanceof</code>
+expression.
+The method <code>edit()</code> in <code>ExprEditor</code>
+receive this object if an instanceof expression is found.
+The method <code>replace()</code> in
+<code>Instanceof</code> receives
+source text representing the substitued statement or
+block for the expression.
+
+In the source text, the identifiers starting with <code>$</code>
+have also special meaning:
+
+<ul><table border=0>
+
+<tr>
+<td><code>$0</code></td>
+<td>
+<code>null</code>.
+</td>
+</tr>
+
+<tr>
+<td><code>$1</code></td>
+<td>
+The value on the left hand side of the original
+<code>instanceof</code> operator.
+</td>
+</tr>
+
+<tr>
+<td><code>$_</code></td>
+<td>
+The resulting value of the expression.
+The type of <code>$_</code> is <code>boolean</code>.
+</td>
+</tr>
+
+<tr>
+<td><code>$r</code></td>
+<td>
+The type on the right hand side of the <code>instanceof</code> operator.
+</td>
+</tr>
+
+<tr><td><code>$type</code></td>
+<td>A <code>java.lang.Class</code> object representing
+the type on the right hand side of the <code>instanceof</code> operator.
+</td>
+</tr>
+
+<tr><td><code>$proceed</code>    </td>
+<td rowspan=4>The name of a virtual method executing the original
+<code>instanceof</code> expression.
+<br>It takes one parameter (the type is <code>java.lang.Object</code>)
+and returns true
+<br>if the parameter value is an instance of the type on the right
+hand side of
+<br>the original <code>instanceof</code> operator.
+Otherwise, it returns false.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+<tr><td> </td></tr>
+<tr><td> </td></tr>
+
+</table>
+</ul>
+
+<p>The other identifiers such as <code>$w</code>,
+<code>$args</code> and <code>$$</code>
+are also available.
+
+<h4>javassist.expr.Cast</h4>
+
+<p>A <code>Cast</code> object represents an expression for
+explicit type casting.
+The method <code>edit()</code> in <code>ExprEditor</code>
+receive this object if explicit type casting is found.
+The method <code>replace()</code> in
+<code>Cast</code> receives
+source text representing the substitued statement or
+block for the expression.
+
+In the source text, the identifiers starting with <code>$</code>
+have also special meaning:
+
+<ul><table border=0>
+
+<tr>
+<td><code>$0</code></td>
+<td>
+<code>null</code>.
+</td>
+</tr>
+
+<tr>
+<td><code>$1</code></td>
+<td>
+The value the type of which is explicitly cast.
+</td>
+</tr>
+
+<tr>
+<td><code>$_</code></td>
+<td rowspan=2>
+The resulting value of the expression.
+The type of <code>$_</code> is the same as the type
+<br>after the explicit casting, that is, the type surrounded
+by <code>( )</code>.
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr>
+<td><code>$r</code></td>
+<td>the type after the explicit casting, or the type surrounded
+by <code>( )</code>.
+</td>
+</tr>
+
+<tr><td><code>$type</code></td>
+<td>A <code>java.lang.Class</code> object representing
+the same type as <code>$r</code>.
+</td>
+</tr>
+
+<tr><td><code>$proceed</code>    </td>
+<td rowspan=3>The name of a virtual method executing the original
+type casting.
+<br>It takes one parameter of the type <code>java.lang.Object</code>
+and returns it after
+<br>the explicit type casting specified by the original expression.
+
+</td>
+</tr>
+
+<tr><td> </td></tr>
+
+<tr><td> </td></tr>
+
+</table>
+</ul>
+
+<p>The other identifiers such as <code>$w</code>,
+<code>$args</code> and <code>$$</code>
+are also available.
+
+<p><br>
+
+<h3>5.3 Adding a new method or field</h3>
+
+<p>Javassist allows the users to create a new method and constructor
+from scratch. <code>CtNewMethod</code>
+and <code>CtNewConstructor</code> provide several factory methods,
+which are static methods for creating <code>CtMethod</code> or
+<code>CtConstructor</code> objects.
+Especially, <code>make()</code> creates
+a <code>CtMethod</code> or <code>CtConstructor</code> object
+from the given source text.
+
+<p>For example, this program:
+
+<ul><pre>
+CtClass point = ClassPool.getDefault().get("Point");
+CtMethod m = CtNewMethod.make(
+ "public int xmove(int dx) { x += dx; }",
+ point);
+point.addMethod(m);
+</pre></ul>
+
+<p>adds a public method <code>xmove()</code> to class <code>Point</code>.
+In this example, <code>x</code> is a <code>int</code> field in
+the class <code>Point</code>.
+
+<p>The source text passed to <code>make()</code> can refer to
+<code>$proceed</code> if the target object and the target method name
+are also given to <code>make()</code>. For example,
+
+<ul><pre>
+CtClass point = ClassPool.getDefault().get("Point");
+CtMethod m = CtNewMethod.make(
+ "public int ymove(int dy) { $proceed(0, dy); }",
+ point, "this", "move");
+</pre></ul>
+
+<p>this program creates a method <code>ymove()</code> defined below:
+
+<ul><pre>
+public int ymove(int dy) { this.move(0, dy); }
+</pre></ul>
+
+<p>Note that <code>$proceed</code> has been replaced with
+<code>this.move</code>.
+
+<p>Javassist also allows the users to create a new field.
+
+<ul><pre>
+CtClass point = ClassPool.getDefault().get("Point");
+CtField f = new CtField(CtClass.intType, "z", point);
+point.addField(f);
+</pre></ul>
+
+<p>This program adds a field named <code>z</code> to class
+<code>Point</code>.
+
+<p>If the initial value of the added field must be specified,
+the program shown above must be modified into:
+
+<ul><pre>
+CtClass point = ClassPool.getDefault().get("Point");
+CtField f = new CtField(CtClass.intType, "z", point);
+point.addField(f, "0"); <em>// initial value is 0.</em>
+</pre></ul>
+
+<p>Now, the method <code>addField()</code> receives the second parameter,
+which is the source text representing an expression computing the initial
+value. This source text can be any Java expression if the result type
+of the expression matches the type of the field. Note that an expression
+does not end with a semi colon (<code>;</code>).
+
+<p><br>
+
+<h3>5.4 Limitations</h3>
+
+<p>In the current implementation, the Java compiler included in Javassist
+has several limitations with respect to the language that the compiler can
+accept. Those limitations are:
+
+<p><li>The <code>.class</code> notation is not supported. Use the
+method <code>Class.forName()</code>.
+In regular
+Java, an expression <code>Point.class</code> means a <code>Class</code>
+object representing the <code>Point</code> class. This notation is
+not available.
+
+<p><li>Array initializers, a comma-separated list of expressions
+enclosed by braces <code>{</code> and <code>}</code>, are not
+supported.
+
+<p><li>Inner classes or anonymous classes are not supported.
+
+<p><li><code>switch</code> statements are not supported yet.
+
+<p><li>Labeled <code>continue</code> and <code>break</code> statements
+are not supported.
+
+<p><li>The <code>finally</code> clause following
+<code>try</code> and <code>catch</code> clauses is not supported.
+
+<p><li>The compiler does not correctly implement the Java method dispatch
+algorithm. The compiler may confuse if methods defined in a class
+have the same name but take different parameter lists.
+
+<p><li>The users are recommended to use <code>#</code> as the separator
+between a class name and a static method or field name.
+For example, in regular Java,
+
+<ul><pre>javassist.CtClass.intType.getName()</pre></ul>
+
+<p>calls a method <code>getName()</code> on
+the object indicated by the static field <code>intType</code>
+in <code>javassist.CtClass</code>. In Javassist, the users can
+write the expression shown above but they are recommended to
+write:
+
+<ul><pre>javassist.CtClass#intType.getName()</pre></ul>
+
+<p>so that the compiler can quickly parse the expression.
+</ul>
+
+<p><br>
+
+<a href="tutorial.html">Previous page</a>
+
+<hr>
+Java(TM) is a trademark of Sun Microsystems, Inc.<br>
+Copyright (C) 2000-2002 by Shigeru Chiba, All rights reserved.
+</body>
+</html>
diff --git a/tutorial/two.gif b/tutorial/two.gif Binary files differnew file mode 100644 index 00000000..ad6984c1 --- /dev/null +++ b/tutorial/two.gif |