]> source.dussan.org Git - javassist.git/commitdiff
Updated the tutorial to be more understandable.
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Thu, 15 Jul 2004 13:49:20 +0000 (13:49 +0000)
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Thu, 15 Jul 2004 13:49:20 +0000 (13:49 +0000)
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@113 30ef5769-5b8d-40dd-aea6-55b5d6557bb3

Readme.html
tutorial/tutorial.html

index 8ce4d36abf5ea877c4bda3469a4740029428e255..59b76998bf49943d4f31601bd87b2462fc3bbb8b 100644 (file)
@@ -555,7 +555,8 @@ Remy Sanlaville, Muga Nishizawa, Alexey Loubyansky, Saori Oki,
 Andreas Salathe, Dante Torres estrada, S. Pam, Nuno Santos,
 Denis Taye, Colin Sampaleanu, Robert Bialek, Asato Shimotaki,
 Howard Lewis Ship, Richard Jones, Marjan Sterjev,
-Bruce McDonald, Mark Brennan, and Vlad Skarzhevskyy.
+Bruce McDonald, Mark Brennan, Vlad Skarzhevskyy,
+and Brett Randall
 for their contributions.
 
 <p><br>
index 6c9df81dad1e5ccd1bbe29315d3b8c0f1a1183f0..0598f60b9477a5e850053fa7cedc25364144eb8f 100644 (file)
@@ -45,50 +45,38 @@ following program is a very simple example:
 ClassPool pool = ClassPool.getDefault();
 CtClass cc = pool.get("test.Rectangle");
 cc.setSuperclass(pool.get("test.Point"));
-cc.writeFile("test.Rectangle");
+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>The <code>ClassPool</code> object is used to maintain one-to-one
-mapping between classes and <code>CtClass</code> objects.  Javassist
-never allows two distinct <code>CtClass</code> objects to represent
-the same class unless two independent <code>ClassPool</code> are created.
-This is a significant feature for consistent program
-transformation.  To create multiple
-instances of <code>ClassPool</code>, write the following code:
-
-<ul><pre>
-ClassPool cp = new ClassPool();
-cp.appendSystemPath(); // or append another path by appendClassPath()
-</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 records the
+constructed object for responding later accesses.
 
-<p>This creates a <code>ClassPool</code> object that behaves as the
-default <code>ClassPool</code> returned by
-<code>ClassPool.getDefault()</code> does.
-<code>ClassPool.getDefault()</code> is a singleton factory method
-provided for convenience.
-
-<p>If you have two <code>ClassPool</code> objects, then you can
-obtain, from each <code>ClassPool</code>, a distinct
-<code>CtClass</code> object representing the same class file.  You can
-differently modify these <code>CtClass</code> objects to generate
-different versions of the class.
-
-<p>To modify the definition of a class, the users must first obtain a
-reference to the <code>CtClass</code> object representing that class.
+To modify the definition of a class, the users must first obtain
+from a <code>ClassPool</code> object
+a reference to a <code>CtClass</code> object representing that class.
 <code>get()</code> in <code>ClassPool</code> is used for this purpose.
-In the case of the program shown at the beginning, the
+In the case of the program shown 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>cc</code>.
+
+<p>From the implementation viewpoint, <code>ClassPool</code> is a hash
+table of <code>CtClass</code> objects, which uses the class names as
+keys.  <code>get()</code> in <code>ClassPool</code> searches this hash
+table to find a <code>CtClass</code> object associated with the
+specified key.  If such a <code>CtClass</code> object is not found,
+<code>get()</code> reads a class file to construct a new
+<code>CtClass</code> object, which is recorded in the hash table and
+then returned as the resulting value of <code>get()</code>.
+
+<p>The <code>CtClass</code> object obtained from a <code>ClassPool</code>
+object can be modified.
+In the example above, 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>writeFile()</code> in <code>CtClass()</code> is
@@ -103,6 +91,8 @@ modified bytecode.  To obtain the bytecode, call <code>toBytecode()</code>:
 byte[] b = cc.toBytecode();
 </pre></ul>
 
+<h4>Class search path</h4>
+
 <p>The default <code>ClassPool</code> returned
 by a static method <code>ClassPool.getDefault()</code>
 searches the same path that the underlying JVM (Java virtual machine) has.
@@ -124,7 +114,6 @@ You can use any <code>Class</code> object as an argument instead of
 <code>this.getClass()</code>.  The class path used for loading the
 class represented by that <code>Class</code> object is registered.
 
-
 <p>
 You can register a directory name as the class search path.
 For example, the following code adds a directory
@@ -221,13 +210,32 @@ CtClass cc = pool.get("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 later called on the <code>ClassPool</code>
-object again, 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.  See the followings:
+<p>This program first obtains the <code>CtClass</code> object for
+class <code>Point</code>.  Then it calls <code>setName()</code> to
+give a new name <code>Pair</code> to that <code>CtClass</code> object.
+After this call, all occurrences of the class name in the class
+definition represented by that <code>CtClass</code> object are changed
+from <code>Point</code> to <code>Pair</code>.  The other part of the
+class definition does not change.
+
+<p>Note that <code>setName()</code> in <code>CtClass</code> changes a
+record in the <code>ClassPool</code> object.  From the implementation
+viewpoint, a <code>ClassPool</code> object is a hash table of
+<code>CtClass</code> objects.  <code>setName()</code> changes
+the key associated to the <code>CtClass</code> object in the hash
+table.  The key is changed from the original class name to the new
+class name.
+
+<p>Therefore, if <code>get("Point")</code> is later called on the
+<code>ClassPool</code> object again, then it never returns the
+<code>CtClass</code> object that the variable <code>cc</code> refers to.
+The <code>ClassPool</code> object reads
+a class file
+<code>Point.class</code> again and it constructs a new <code>CtClass</code>
+object for class <code>Point</code>.
+This is because the <code>CtClass</code> object associated with the name
+<code>Point</code> does not exist any more.
+See the followings:
 
 <ul><pre>
 ClassPool pool = ClassPool.getDefault();
@@ -238,6 +246,38 @@ CtClass cc2 = pool.get("Pair");    // cc2 is identical to cc.
 CtClass cc3 = pool.get("Point");   // cc3 is not identical to cc.
 </pre></ul>
 
+<p><code>cc1</code> and <code>cc2</code> refer to the same instance of
+<code>CtClass</code> that <code>cc</code> does whereas
+<code>cc3</code> does not.  Note that, after
+<code>cc.setName("Pair")</code> is executed, the <code>CtClass</code>
+object that <code>cc</code> and <code>cc1</code> refer to represents
+the <code>Pair</code> class.
+
+<p>The <code>ClassPool</code> object is used to maintain one-to-one
+mapping between classes and <code>CtClass</code> objects.  Javassist
+never allows two distinct <code>CtClass</code> objects to represent
+the same class unless two independent <code>ClassPool</code> are created.
+This is a significant feature for consistent program
+transformation.  To create multiple
+instances of <code>ClassPool</code>, write the following code:
+
+<ul><pre>
+ClassPool cp = new ClassPool();
+cp.appendSystemPath(); // or append another path by appendClassPath()
+</pre></ul>
+
+<p>This creates a <code>ClassPool</code> object that behaves as the
+default <code>ClassPool</code> returned by
+<code>ClassPool.getDefault()</code> does.
+<code>ClassPool.getDefault()</code> is a singleton factory method
+provided for convenience.
+
+<p>If you have two <code>ClassPool</code> objects, then you can
+obtain, from each <code>ClassPool</code>, a distinct
+<code>CtClass</code> object representing the same class file.  You can
+differently modify these <code>CtClass</code> objects to generate
+different versions of the class.
+
 <p>Once a <code>CtClass</code> object is converted into a class file
 by <code>writeFile()</code> or <code>toBytecode()</code>, Javassist
 rejects further modifications of that <code>CtClass</code> object.
@@ -245,20 +285,33 @@ Hence, after the <code>CtClass</code> object representing <code>Point</code>
 class is converted into a class file, you cannot define <code>Pair</code>
 class as a copy of <code>Point</code> since executing <code>setName()</code>
 on <code>Point</code> is rejected.
+The following code snippet is wrong:
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.get("Point");
+cc.writeFile();
+cc.setName("Pair");    // wrong since writeFile() has been called.
+</pre></ul>
 
 <p>To avoid this restriction, you should call <code>getAndRename()</code>
 in <code>ClassPool</code>.  For example,
 
 <ul><pre>
 ClassPool pool = ClassPool.getDefault();
-CtClass cc = pool.getAndRename("Point", "Pair");
+CtClass cc = pool.get("Point");
+cc.writeFile();
+CtClass cc2 = pool.getAndRename("Point", "Pair");
 </pre></ul>
 
 <p>If <code>getAndRename()</code> is called, the <code>ClassPool</code>
-reads <code>Point.class</code> for creating a new <code>CtClass</code>
-object representing <code>Pair</code> class.  <code>getAndRename()</code>
+first reads <code>Point.class</code> for creating a new <code>CtClass</code>
+object representing <code>Point</code> class.  However, it renames that
+<code>CtClass</code> object from <code>Point</code> to <code>Pair</code> before
+it records that <code>CtClass</code> object in a hash table.
+Thus <code>getAndRename()</code>
 can be executed after <code>writeFile()</code> or <code>toBytecode()</code>
-is called on the the <code>ClassPool</code> representing <code>Point</code>
+is called on the the <code>CtClass</code> object representing <code>Point</code>
 class.