123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- <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="tutorial2.html">Previous page</a></div>
-
- <p>
- <a href="#intro">5. Bytecode level API</a>
- <ul>
- <li><a href="#classfile">Obtaining a <code>ClassFile</code> object</a>
- <br><li><a href="#member">Adding and removing a member</a>
- <br><li><a href="#traverse">Traversing a method body</a>
- <br><li><a href="#bytecode">Producing a bytecode sequence</a>
- <br><li><a href="#annotation">Annotations (Meta tags)</a>
-
- </ul>
-
- <p><a href="#generics">6. Generics</a>
-
- <p><br>
-
- <a name="intro">
- <h2>5. Bytecode level API</h2>
-
- <p>
- Javassist also provides lower-level API for directly editing
- a class file. To use this level of API, you need detailed
- knowledge of the Java bytecode and the class file format
- while this level of API allows you any kind of modification
- of class files.
-
- <a name="classfile">
- <h3>5.1 Obtaining a <code>ClassFile</code> object</h3>
-
- <p>A <code>javassist.bytecode.ClassFile</code> object represents
- a class file. To obtian this object, <code>getClassFile()</code>
- in <code>CtClass</code> should be called.
-
- <p>Otherwise, you can construct a
- <code>javassist.bytecode.ClassFile</code> directly from a class file.
- For example,
-
- <ul><pre>
- BufferedInputStream fin
- = new BufferedInputStream(new FileInputStream("Point.class"));
- ClassFile cf = new ClassFile(new DataInputStream(fin));
- </pre></ul>
-
- <p>
- This code snippet creats a <code>ClassFile</code> object from
- <code>Point.class</code>.
-
- <p>
- A <code>ClassFile</code> object can be written back to a
- class file. <code>write()</code> in <code>ClassFile</code>
- writes the contents of the class file to a given
- <code>DataOutputStream</code>.
-
- <p><br>
-
- <a name="member">
- <h3>5.2 Adding and removing a member</h3>
-
- <p>
- <code>ClassFile</code> provides <code>addField()</code> and
- <code>addMethod()</code> for adding a field or a method (note that
- a constructor is regarded as a method at the bytecode level).
- It also provides <code>addAttribute()</code> for adding an attribute
- to the class file.
-
- <p>
- Note that <code>FieldInfo</code>, <code>MethodInfo</code>, and
- <code>AttributeInfo</code> objects include a link to a
- <code>ConstPool</code> (constant pool table) object. The <code>ConstPool</code>
- object must be common to the <code>ClassFile</code> object and
- a <code>FieldInfo</code> (or <code>MethodInfo</code> etc.) object
- that is added to that <code>ClassFile</code> object.
- In other words, a <code>FieldInfo</code> (or <code>MethodInfo</code> etc.) object
- must not be shared among different <code>ClassFile</code> objects.
-
- <p>
- To remove a field or a method from a <code>ClassFile</code> object,
- you must first obtain a <code>java.util.List</code>
- object containing all the fields of the class. <code>getFields()</code>
- and <code>getMethods()</code> return the lists. A field or a method can
- be removed by calling <code>remove()</code> on the <code>List</code> object.
- An attribute can be removed in a similar way.
- Call <code>getAttributes()</code> in <code>FieldInfo</code> or
- <code>MethodInfo</code> to obtain the list of attributes,
- and remove one from the list.
-
-
- <p><br>
-
- <a name="traverse">
- <h3>5.3 Traversing a method body</h3>
-
- <p>
- To examine every bytecode instruction in a method body,
- <code>CodeIterator</code> is useful. To otbain this object,
- do as follows:
-
- <ul><pre>
- ClassFile cf = ... ;
- MethodInfo minfo = cf.getMethod("move"); // we assume move is not overloaded.
- CodeAttribute ca = minfo.getCodeAttribute();
- CodeIterator i = ca.iterator();
- </pre></ul>
-
- <p>
- A <code>CodeIterator</code> object allows you to visit every
- bytecode instruction one by one from the beginning to the end.
- The following methods are part of the methods declared in
- <code>CodeIterator</code>:
-
- <ul>
- <li><code>void begin()</code><br>
- Move to the first instruction.<br>
- <li><code>void move(int index)</code><br>
- Move to the instruction specified by the given index.<br>
- <li><code>boolean hasNext()</code><br>
- Returns true if there is more instructions.<br>
- <li><code>int next()</code><br>
- Returns the index of the next instruction.<br>
- <em>Note that it does not return the opcode of the next
- instruction.</em><br>
- <li><code>int byteAt(int index)</code><br>
- Returns the unsigned 8bit value at the index.<br>
- <li><code>int u16bitAt(int index)</code><br>
- Returns the unsigned 16bit value at the index.<br>
- <li><code>int write(byte[] code, int index)</code><br>
- Writes a byte array at the index.<br>
- <li><code>void insert(int index, byte[] code)</code><br>
- Inserts a byte array at the index.
- Branch offsets etc. are automatically adjusted.<br>
- </ul>
-
- <p>The following code snippet displays all the instructions included
- in a method body:
-
- <ul><pre>
- CodeIterator ci = ... ;
- while (ci.hasNext()) {
- int index = ci.next();
- int op = ci.byteAt(index);
- System.out.println(Mnemonic.OPCODE[op]);
- }
- </pre></ul>
-
- <p><br>
-
- <a name="bytecode">
- <h3>5.4 Producing a bytecode sequence</h3>
-
- <p>
- A <code>Bytecode</code> object represents a sequence of bytecode
- instructions. It is a growable array of bytecode.
- Here is a sample code snippet:
-
- <ul><pre>
- ConstPool cp = ...; // constant pool table
- Bytecode b = new Bytecode(cp, 1, 0);
- b.addIconst(3);
- b.addReturn(CtClass.intType);
- CodeAttribute ca = b.toCodeAttribute();
- </pre></ul>
-
- <p>
- This produces the code attribute representing the following sequence:
-
- <ul><pre>
- iconst_3
- ireturn
- </pre></ul>
-
- <p>
- You can also obtain a byte array containing this sequence by
- calling <code>get()</code> in <code>Bytecode</code>. The
- obtained array can be inserted in another code attribute.
-
- <p>
- While <code>Bytecode</code> provides a number of methods for adding a
- specific instruction to the sequence, it provides
- <code>addOpcode()</code> for adding an 8bit opcode and
- <code>addIndex()</code> for adding an index.
- The 8bit value of each opcode is defined in the <code>Opcode</code>
- interface.
-
- <p>
- <code>addOpcode()</code> and other methods for adding a specific
- instruction are automatically maintain the maximum stack depth
- unless the control flow does not include a branch.
- This value can be obtained by calling <code>getMaxStack()</code>
- on the <code>Bytecode</code> object.
- It is also reflected on the <code>CodeAttribute</code> object
- constructed from the <code>Bytecode</code> object.
- To recompute the maximum stack depth of a method body,
- call <code>computeMaxStack()</code> in <code>CodeAttribute</code>.
-
- <p><br>
-
- <a name="annotation">
- <h3>5.5 Annotations (Meta tags)</h3>
-
- <p>Annotations are stored in a class file
- as runtime invisible (or visible) annotations attribute.
- These attributes can be obtained from <code>ClassFile</code>,
- <code>MethodInfo</code>, or <code>FieldInfo</code> objects.
- Call <code>getAttribute(AnnotationsAttribute.invisibleTag)</code>
- on those objects. For more details, see the javadoc manual
- of <code>javassist.bytecode.AnnotationsAttribute</code> class
- and the <code>javassist.bytecode.annotation</code> package.
-
- <p>Javassist also let you access annotations by the higher-level
- API.
- If you want to access annotations through <code>CtClass</code>,
- call <code>getAnnotations()</code> in <code>CtClass</code> or
- <code>CtBehavior</code>.
-
- <p><br>
-
- <h2><a name="generics">6. Generics</a></h2>
-
- <p>The lower-level API of Javassist fully supports generics
- introduced by Java 5. On the other hand, the higher-level
- API such as <code>CtClass</code> does not directly support
- generics. However, this is not a serious problem for bytecode
- transformation.
-
- <p>The generics of Java is implemented by the erasure technique.
- After compilation, all type parameters are dropped off. For
- example, suppose that your source code declares a parameterized
- type <code>Vector<String></code>:
-
- <ul><pre>
- Vector<String> v = new Vector<String>();
- :
- String s = v.get(0);
- </pre></ul>
-
- <p>The compiled bytecode is equivalent to the following code:
-
- <ul><pre>
- Vector v = new Vector();
- :
- String s = (String)v.get(0);
- </pre></ul>
-
- <p>So when you write a bytecode transformer, you can just drop
- off all type parameters. For example, if you have a class:
-
- <ul><pre>
- public class Wrapper<T> {
- T value;
- public Wrapper(T t) { value = t; }
- }
- </pre></ul>
-
- <p>and want to add an interface <code>Getter<T></code> to the
- class <code>Wrapper<T></code>:
-
- <ul><pre>
- public interface Getter<T> {
- T get();
- }
- </pre></ul>
-
- <p>Then the interface you really have to add is <code>Getter</code>
- (the type parameters <code><T></code> drops off)
- and the method you also have to add to the <code>Wrapper</code>
- class is this simple one:
-
- <ul><pre>
- public Object get() { return value; }
- </pre></ul>
-
- <p>Note that no type parameters are necessary.
-
- <p><br>
-
- <a href="tutorial2.html">Previous page</a>
-
- <hr>
- Java(TM) is a trademark of Sun Microsystems, Inc.<br>
- Copyright (C) 2000-2007 by Shigeru Chiba, All rights reserved.
- </body>
- </html>
|