/Users/lyon/j4p/src/javassist/CtClass.java

1    /* 
2     * Javassist, a Java-bytecode translator toolkit. 
3     * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved. 
4     * 
5     * The contents of this file are subject to the Mozilla Public License Version 
6     * 1.1 (the "License"); you may not use this file except in compliance with 
7     * the License.  Alternatively, the contents of this file may be used under 
8     * the terms of the GNU Lesser General Public License Version 2.1 or later. 
9     * 
10    * Software distributed under the License is distributed on an "AS IS" basis, 
11    * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
12    * for the specific language governing rights and limitations under the 
13    * License. 
14    */ 
15    
16   package javassist; 
17    
18   import javassist.bytecode.ClassFile; 
19   import javassist.bytecode.Descriptor; 
20   import javassist.bytecode.Opcode; 
21   import javassist.expr.ExprEditor; 
22    
23   import java.io.DataOutputStream; 
24   import java.io.IOException; 
25   import java.util.Collection; 
26    
27   // Subclasses of CtClass: CtClassType, CtPrimitiveType, and CtArray 
28    
29   /** 
30    * An instance of <code>CtClass</code> represents a class. 
31    * It is obtained from <code>ClassPool</code>. 
32    * 
33    * @see ClassPool#get(String) 
34    */ 
35   public abstract class CtClass { 
36       protected String qualifiedName; 
37    
38       /** 
39        * The version number of this release. 
40        */ 
41       public static final String version = "2.6"; 
42    
43       static final String javaLangObject = "java.lang.Object"; 
44    
45       /** 
46        * The <code>CtClass</code> object representing 
47        * the <code>boolean</code> type. 
48        */ 
49       public static CtClass booleanType; 
50    
51       /** 
52        * The <code>CtClass</code> object representing 
53        * the <code>char</code> type. 
54        */ 
55       public static CtClass charType; 
56    
57       /** 
58        * The <code>CtClass</code> object representing 
59        * the <code>byte</code> type. 
60        */ 
61       public static CtClass byteType; 
62    
63       /** 
64        * The <code>CtClass</code> object representing 
65        * the <code>short</code> type. 
66        */ 
67       public static CtClass shortType; 
68    
69       /** 
70        * The <code>CtClass</code> object representing 
71        * the <code>int</code> type. 
72        */ 
73       public static CtClass intType; 
74    
75       /** 
76        * The <code>CtClass</code> object representing 
77        * the <code>long</code> type. 
78        */ 
79       public static CtClass longType; 
80    
81       /** 
82        * The <code>CtClass</code> object representing 
83        * the <code>float</code> type. 
84        */ 
85       public static CtClass floatType; 
86    
87       /** 
88        * The <code>CtClass</code> object representing 
89        * the <code>double</code> type. 
90        */ 
91       public static CtClass doubleType; 
92    
93       /** 
94        * The <code>CtClass</code> object representing 
95        * the <code>void</code> type. 
96        */ 
97       public static CtClass voidType; 
98    
99       static CtClass[] primitiveTypes; 
100   
101      static { 
102          primitiveTypes = new CtClass[9]; 
103   
104          booleanType = new CtPrimitiveType("boolean", 'Z', "java.lang.Boolean", 
105                  "booleanValue", "()Z", Opcode.IRETURN, 
106                  Opcode.T_BOOLEAN, 1); 
107          primitiveTypes[0] = booleanType; 
108   
109          charType = new CtPrimitiveType("char", 'C', "java.lang.Character", 
110                  "charValue", "()C", Opcode.IRETURN, 
111                  Opcode.T_CHAR, 1); 
112          primitiveTypes[1] = charType; 
113   
114          byteType = new CtPrimitiveType("byte", 'B', "java.lang.Byte", 
115                  "byteValue", "()B", Opcode.IRETURN, 
116                  Opcode.T_BYTE, 1); 
117          primitiveTypes[2] = byteType; 
118   
119          shortType = new CtPrimitiveType("short", 'S', "java.lang.Short", 
120                  "shortValue", "()S", Opcode.IRETURN, 
121                  Opcode.T_SHORT, 1); 
122          primitiveTypes[3] = shortType; 
123   
124          intType = new CtPrimitiveType("int", 'I', "java.lang.Integer", 
125                  "intValue", "()I", Opcode.IRETURN, 
126                  Opcode.T_INT, 1); 
127          primitiveTypes[4] = intType; 
128   
129          longType = new CtPrimitiveType("long", 'J', "java.lang.Long", 
130                  "longValue", "()J", Opcode.LRETURN, 
131                  Opcode.T_LONG, 2); 
132          primitiveTypes[5] = longType; 
133   
134          floatType = new CtPrimitiveType("float", 'F', "java.lang.Float", 
135                  "floatValue", "()F", Opcode.FRETURN, 
136                  Opcode.T_FLOAT, 1); 
137          primitiveTypes[6] = floatType; 
138   
139          doubleType = new CtPrimitiveType("double", 'D', "java.lang.Double", 
140                  "doubleValue", "()D", Opcode.DRETURN, 
141                  Opcode.T_DOUBLE, 2); 
142          primitiveTypes[7] = doubleType; 
143   
144          voidType = new CtPrimitiveType("void", 'V', "java.lang.Void", 
145                  null, null, Opcode.RETURN, 0, 0); 
146          primitiveTypes[8] = voidType; 
147      } 
148   
149      protected CtClass(String name) { 
150          qualifiedName = name; 
151      } 
152   
153      /** 
154       * Returns a <code>ClassPool</code> for this class. 
155       */ 
156      public ClassPool getClassPool() { 
157          return null; 
158      } 
159   
160      /** 
161       * Returns a class file for this class. 
162       * 
163       * <p>This method is not available if <code>isFrozen()</code> 
164       * is true. 
165       */ 
166      public ClassFile getClassFile() { 
167          checkModify(); 
168          return getClassFile2(); 
169      } 
170   
171      /** 
172       * Undocumented method.  Do not use; internal-use only. 
173       */ 
174      public ClassFile getClassFile2() { 
175          return null; 
176      } 
177   
178      /** 
179       * Returns true if the definition of the class has been modified. 
180       */ 
181      public boolean isModified() { 
182          return false; 
183      } 
184   
185      /** 
186       * Returns true if the class has been loaded or written out 
187       * and thus it cannot be modified any more. 
188       * 
189       * @see #defrost() 
190       */ 
191      public boolean isFrozen() { 
192          return true; 
193      } 
194   
195      void freeze() { 
196      } 
197   
198      void checkModify() throws RuntimeException { 
199          if (isFrozen()) 
200              throw new RuntimeException("the class is frozen"); 
201   
202          // isModified() must return true after this method is invoked. 
203      } 
204   
205      /** 
206       * Defrosts the class so that the class can be modified again. 
207       * 
208       * To avoid changes that will be never reflected, 
209       * the class is frozen to be unmodifiable if it is loaded or 
210       * written out.  This method should be called only in a case 
211       * that the class will be reloaded or written out later again. 
212       * 
213       * @see #isFrozen() 
214       */ 
215      public void defrost() { 
216          throw new RuntimeException("cannot defrost " + getName()); 
217      } 
218   
219      /** 
220       * Returns <code>true</code> if this object represents a primitive 
221       * Java type: boolean, byte, char, short, int, long, float, double, 
222       * or void. 
223       */ 
224      public boolean isPrimitive() { 
225          return false; 
226      } 
227   
228      /** 
229       * Returns <code>true</code> if this object represents an array type. 
230       */ 
231      public boolean isArray() { 
232          return false; 
233      } 
234   
235      /** 
236       * If this object represents an array, this method returns the component 
237       * type of the array.  Otherwise, it returns <code>null</code>. 
238       */ 
239      public CtClass getComponentType() throws NotFoundException { 
240          return null; 
241      } 
242   
243      /** 
244       * Returns <code>true</code> if this class extends or implements 
245       * <code>clazz</code>.  It also returns <code>true</code> if 
246       * this class is the same as <code>clazz</code>. 
247       */ 
248      public boolean subtypeOf(CtClass clazz) throws NotFoundException { 
249          return this == clazz || getName().equals(clazz.getName()); 
250      } 
251   
252      /** 
253       * Obtains the fully-qualified name of the class. 
254       */ 
255      public String getName() { 
256          return qualifiedName; 
257      } 
258   
259      /** 
260       * Obtains the not-qualified class name. 
261       */ 
262      public final String getSimpleName() { 
263          String qname = qualifiedName; 
264          int index = qname.lastIndexOf('.'); 
265          if (index < 0) 
266              return qname; 
267          else 
268              return qname.substring(index + 1); 
269      } 
270   
271      /** 
272       * Obtains the package name.  It may be <code>null</code>. 
273       */ 
274      public final String getPackageName() { 
275          String qname = qualifiedName; 
276          int index = qname.lastIndexOf('.'); 
277          if (index < 0) 
278              return null; 
279          else 
280              return qname.substring(0, index); 
281      } 
282   
283      /** 
284       * Sets the class name 
285       * 
286       * @param name      fully-qualified name 
287       */ 
288      public void setName(String name) { 
289          checkModify(); 
290          if (name != null) 
291              qualifiedName = name; 
292      } 
293   
294      /** 
295       * Substitutes <code>newName</code> for all occurrences of a class 
296       * name <code>oldName</code> in the class file. 
297       * 
298       * @param oldname           replaced class name 
299       * @param newname           substituted class name 
300       */ 
301      public void replaceClassName(String oldname, String newname) { 
302          checkModify(); 
303      } 
304   
305      /** 
306       * Changes class names appearing in the class file according to the 
307       * given <code>map</code>. 
308       * 
309       * <p>All the class names appearing in the class file are tested 
310       * with <code>map</code> to determine whether each class name is 
311       * replaced or not.  Thus this method can be used for collecting 
312       * all the class names in the class file.  To do that, first define 
313       * a subclass of <code>ClassMap</code> so that <code>get()</code> 
314       * records all the given parameters.  Then, make an instance of 
315       * that subclass as an empty hash-table.  Finally, pass that instance 
316       * to this method.  After this method finishes, that instance would 
317       * contain all the class names appearing in the class file. 
318       * 
319       * @param map       the hashtable associating replaced class names 
320       *                  with substituted names. 
321       */ 
322      public void replaceClassName(ClassMap map) { 
323          checkModify(); 
324      } 
325   
326      /** 
327       * Returns a collection of the names of all the classes 
328       * referenced in this class. 
329       * That collection includes the name of this class. 
330       * 
331       * <p>This method may return <code>null</code>. 
332       */ 
333      public Collection getRefClasses() { 
334          ClassFile cf = getClassFile2(); 
335          if (cf != null) { 
336              ClassMap cm = new ClassMap() { 
337                  public void put(String oldname, String newname) { 
338                      put0(oldname, newname); 
339                  } 
340   
341                  public Object get(Object jvmClassName) { 
342                      String n = toJavaName((String) jvmClassName); 
343                      put0(n, n); 
344                      return null; 
345                  } 
346   
347                  public void fix(String name) { 
348                  } 
349              }; 
350              cf.renameClass(cm); 
351              return cm.values(); 
352          } else 
353              return null; 
354      } 
355   
356      /** 
357       * Determines whether this object represents a class or an interface. 
358       * It returns <code>true</code> if this object represents an interface. 
359       */ 
360      public boolean isInterface() { 
361          return false; 
362      } 
363   
364      /** 
365       * Returns the modifiers for this class, encoded in an integer. 
366       * For decoding, use <code>javassist.Modifier</code>. 
367       * 
368       * @see Modifier 
369       */ 
370      public int getModifiers() { 
371          return 0; 
372      } 
373   
374      /** 
375       * Sets the modifiers. 
376       * 
377       * @param mod       modifiers encoded by 
378       *                  <code>javassist.Modifier</code> 
379       * @see Modifier 
380       */ 
381      public void setModifiers(int mod) { 
382          checkModify(); 
383      } 
384   
385      /** 
386       * Determines whether the class directly or indirectly extends 
387       * the given class.  If this class extends a class A and 
388       * the class A extends a class B, then subclassof(B) returns true. 
389       * 
390       * <p>This method returns true if the given class is identical to 
391       * the class represented by this object. 
392       */ 
393      public boolean subclassOf(CtClass superclass) { 
394          return false; 
395      } 
396   
397      /** 
398       * Obtains the class object representing the superclass of the 
399       * class. 
400       * It returns null if this object represents the 
401       * <code>java.lang.Object</code> class and thus it does not have 
402       * the super class. 
403       */ 
404      public CtClass getSuperclass() throws NotFoundException { 
405          return null; 
406      } 
407   
408      /** 
409       * Changes a super class.  The new super class must be compatible 
410       * with the old one. 
411       */ 
412      public void setSuperclass(CtClass clazz) throws CannotCompileException { 
413          checkModify(); 
414      } 
415   
416      /** 
417       * Obtains the class objects representing the interfaces of the 
418       * class. 
419       */ 
420      public CtClass[] getInterfaces() throws NotFoundException { 
421          return new CtClass[0]; 
422      } 
423   
424      /** 
425       * Sets interfaces. 
426       * 
427       * @param list              a list of the <code>CtClass</code> objects 
428       *                          representing interfaces, or 
429       *                          <code>null</code> if the class implements 
430       *                          no interfaces. 
431       */ 
432      public void setInterfaces(CtClass[] list) { 
433          checkModify(); 
434      } 
435   
436      /** 
437       * Adds an interface. 
438       * 
439       * @param anInterface       the added interface. 
440       */ 
441      public void addInterface(CtClass anInterface) { 
442          checkModify(); 
443      } 
444   
445      /** 
446       * Returns an array containing <code>CtField</code> objects 
447       * representing all the public fields of the class. 
448       * That array includes public fields inherited from the 
449       * superclasses. 
450       */ 
451      public CtField[] getFields() { 
452          return new CtField[0]; 
453      } 
454   
455      /** 
456       * Returns the field with the specified name.  The returned field 
457       * may be a private field declared in a super class or interface. 
458       */ 
459      public CtField getField(String name) throws NotFoundException { 
460          throw new NotFoundException(name); 
461      } 
462   
463      /** 
464       * Gets all the fields declared in the class.  The inherited fields 
465       * are not included. 
466       * 
467       * <p>Note: the result does not include inherited fields. 
468       */ 
469      public CtField[] getDeclaredFields() { 
470          return new CtField[0]; 
471      } 
472   
473      /** 
474       * Retrieves the field with the specified name among the fields 
475       * declared in the class. 
476       * 
477       * <p>Note: this method does not search the superclasses. 
478       */ 
479      public CtField getDeclaredField(String name) throws NotFoundException { 
480          throw new NotFoundException(name); 
481      } 
482   
483      /** 
484       * Gets all the constructors and methods declared in the class. 
485       */ 
486      public CtBehavior[] getDeclaredBehaviors() { 
487          return new CtBehavior[0]; 
488      } 
489   
490      /** 
491       * Returns an array containing <code>CtConstructor</code> objects 
492       * representing all the public constructors of the class. 
493       */ 
494      public CtConstructor[] getConstructors() { 
495          return new CtConstructor[0]; 
496      } 
497   
498      /** 
499       * Returns the constructor with the given signature, 
500       * which is represented by a character string 
501       * called method descriptor. 
502       * For details of the method descriptor, see the JVM specification 
503       * or <code>javassist.bytecode.Descriptor</code>. 
504       * 
505       * @param desc      method descriptor 
506       * @see javassist.bytecode.Descriptor 
507       */ 
508      public CtConstructor getConstructor(String desc) 
509              throws NotFoundException { 
510          throw new NotFoundException("no such a constructor"); 
511      } 
512   
513      /** 
514       * Gets all the constructors declared in the class. 
515       * 
516       * @see javassist.CtConstructor 
517       */ 
518      public CtConstructor[] getDeclaredConstructors() { 
519          return new CtConstructor[0]; 
520      } 
521   
522      /** 
523       * Returns a constructor receiving the specified parameters. 
524       * 
525       * @param params    parameter types. 
526       */ 
527      public CtConstructor getDeclaredConstructor(CtClass[] params) 
528              throws NotFoundException { 
529          String desc = Descriptor.ofConstructor(params); 
530          return getConstructor(desc); 
531      } 
532   
533      /** 
534       * Gets the class initializer (static constructor) 
535       * declared in the class. 
536       * This method returns <code>null</code> if 
537       * no class initializer is not declared. 
538       * 
539       * @see #makeClassInitializer() 
540       * @see javassist.CtConstructor 
541       */ 
542      public CtConstructor getClassInitializer() { 
543          return null; 
544      } 
545   
546      /** 
547       * Returns an array containing <code>CtMethod</code> objects 
548       * representing all the public methods of the class. 
549       * That array includes public methods inherited from the 
550       * superclasses. 
551       */ 
552      public CtMethod[] getMethods() { 
553          return new CtMethod[0]; 
554      } 
555   
556      /** 
557       * Returns the method with the given name and signature. 
558       * The returned method may be declared in a super class. 
559       * The method signature is represented by a character string 
560       * called method descriptor, 
561       * which is defined in the JVM specification. 
562       * 
563       * @param name      method name 
564       * @param desc      method descriptor 
565       * @see javassist.bytecode.Descriptor 
566       */ 
567      public CtMethod getMethod(String name, String desc) 
568              throws NotFoundException { 
569          throw new NotFoundException(name); 
570      } 
571   
572      /** 
573       * Gets all methods declared in the class.  The inherited methods 
574       * are not included. 
575       * 
576       * @see javassist.CtMethod 
577       */ 
578      public CtMethod[] getDeclaredMethods() { 
579          return new CtMethod[0]; 
580      } 
581   
582      /** 
583       * Retrieves the method with the specified name and parameter types 
584       * among the methods declared in the class. 
585       * 
586       * <p>Note: this method does not search the superclasses. 
587       * 
588       * @param name              method name 
589       * @param params            parameter types 
590       * @see javassist.CtMethod 
591       */ 
592      public CtMethod getDeclaredMethod(String name, CtClass[] params) 
593              throws NotFoundException { 
594          throw new NotFoundException(name); 
595      } 
596   
597      /** 
598       * Retrieves the method with the specified name among the methods 
599       * declared in the class.  If there are multiple methods with 
600       * the specified name, then this method returns one of them. 
601       * 
602       * <p>Note: this method does not search the superclasses. 
603       * 
604       * @see javassist.CtMethod 
605       */ 
606      public CtMethod getDeclaredMethod(String name) throws NotFoundException { 
607          throw new NotFoundException(name); 
608      } 
609   
610      /** 
611       * Makes a class initializer (static constructor). 
612       * If the class already includes a class initializer, 
613       * this method returns it. 
614       * 
615       * @see #getClassInitializer() 
616       */ 
617      public CtConstructor makeClassInitializer() 
618              throws CannotCompileException { 
619          throw new CannotCompileException("not a class"); 
620      } 
621   
622      /** 
623       * Adds a constructor. 
624       */ 
625      public void addConstructor(CtConstructor c) 
626              throws CannotCompileException { 
627          checkModify(); 
628      } 
629   
630      /** 
631       * Adds a method. 
632       */ 
633      public void addMethod(CtMethod m) throws CannotCompileException { 
634          checkModify(); 
635      } 
636   
637      /** 
638       * Adds a field. 
639       * 
640       * <p>The <code>CtField</code> belonging to another 
641       * <code>CtClass</code> cannot be directly added to this class. 
642       * Only a field created for this class can be added. 
643       * 
644       * @see javassist.CtField#CtField(CtField,CtClass) 
645       */ 
646      public void addField(CtField f) throws CannotCompileException { 
647          addField(f, (CtField.Initializer) null); 
648      } 
649   
650      /** 
651       * Adds a field with an initial value. 
652       * 
653       * <p>The <code>CtField</code> belonging to another 
654       * <code>CtClass</code> cannot be directly added to this class. 
655       * Only a field created for this class can be added. 
656       * 
657       * <p>The initial value is given as an expression written in Java. 
658       * Any regular Java expression can be used for specifying the initial 
659       * value.  The followings are examples. 
660       * 
661       * <ul><pre> 
662       * cc.addField(f, "0")               // the initial value is 0. 
663       * cc.addField(f, "i + 1")           // i + 1. 
664       * cc.addField(f, "new Point()");    // a Point object. 
665       * </pre></ul> 
666       * 
667       * <p>Here, the type of variable <code>cc</code> is <code>CtClass</code>. 
668       * The type of <code>f</code> is <code>CtField</code>. 
669       * 
670       * @param init      an expression for the initial value. 
671       * 
672       * @see javassist.CtField.Initializer#byExpr(String) 
673       * @see javassist.CtField#CtField(CtField,CtClass) 
674       */ 
675      public void addField(CtField f, String init) 
676              throws CannotCompileException { 
677          checkModify(); 
678      } 
679   
680      /** 
681       * Adds a field with an initial value. 
682       * 
683       * <p>The <code>CtField</code> belonging to another 
684       * <code>CtClass</code> cannot be directly added to this class. 
685       * Only a field created for this class can be added. 
686       * 
687       * <p>For example, 
688       * 
689       * <ul><pre> 
690       * CtClass cc = ...; 
691       * addField(new CtField(CtClass.intType, "i", cc), 
692       *          CtField.Initializer.constant(1)); 
693       * </pre></ul> 
694       * 
695       * <p>This code adds an <code>int</code> field named "i".  The 
696       * initial value of this field is 1. 
697       * 
698       * @param init      specifies the initial value of the field. 
699       * 
700       * @see javassist.CtField#CtField(CtField,CtClass) 
701       */ 
702      public void addField(CtField f, CtField.Initializer init) 
703              throws CannotCompileException { 
704          checkModify(); 
705      } 
706   
707      /** 
708       * Obtains an attribute with the given name. 
709       * If that attribute is not found in the class file, this 
710       * method returns null. 
711       * 
712       * @param name              attribute name 
713       */ 
714      public byte[] getAttribute(String name) { 
715          return null; 
716      } 
717   
718      /** 
719       * Adds a named attribute. 
720       * An arbitrary data (smaller than 64Kb) can be saved in the class 
721       * file.  Some attribute name are reserved by the JVM. 
722       * The attributes with the non-reserved names are ignored when a 
723       * class file is loaded into the JVM. 
724       * If there is already an attribute with 
725       * the same name, this method substitutes the new one for it. 
726       * 
727       * @param name      attribute name 
728       * @param data      attribute value 
729       */ 
730      public void setAttribute(String name, byte[] data) { 
731          checkModify(); 
732      } 
733   
734      /** 
735       * Applies the given converter to all methods and constructors 
736       * declared in the class.  This method calls <code>instrument()</code> 
737       * on every <code>CtMethod</code> and <code>CtConstructor</code> object 
738       * in the class. 
739       * 
740       * @param converter         specifies how to modify. 
741       */ 
742      public void instrument(CodeConverter converter) 
743              throws CannotCompileException { 
744          checkModify(); 
745      } 
746   
747      /** 
748       * Modifies the bodies of all methods and constructors 
749       * declared in the class.  This method calls <code>instrument()</code> 
750       * on every <code>CtMethod</code> and <code>CtConstructor</code> object 
751       * in the class. 
752       * 
753       * @param editor            specifies how to modify. 
754       */ 
755      public void instrument(ExprEditor editor) 
756              throws CannotCompileException { 
757          checkModify(); 
758      } 
759   
760      /** 
761       * Converts this class to a <code>java.lang.Class</code> object. 
762       * Once this method is called, further modifications are not 
763       * possible any more. 
764       * 
765       * <p>This method is equivalent to: 
766       * <ul><pre>this.getClassPool().writeAsClass(this.getName())</pre></ul> 
767       * 
768       * <p>See the description of <code>ClassPool.writeAsClass()</code> 
769       * before you use this method. 
770       * This method is provided for convenience.  If you need more 
771       * complex functionality, you should write your own class loader. 
772       * 
773       * @see javassist.ClassPool#writeAsClass(String) 
774       * @see javassist.ClassPool#forName(String) 
775       */ 
776      public Class toClass() 
777              throws NotFoundException, IOException, CannotCompileException { 
778          return getClassPool2().writeAsClass(getName()); 
779      } 
780   
781      /** 
782       * Converts this class to a class file. 
783       * Once this method is called, further modifications are not 
784       * possible any more. 
785       * 
786       * <p>This method is equivalent to: 
787       * <ul><pre>this.getClassPool().write(this.getName())</pre></ul> 
788       * 
789       * @see javassist.ClassPool#write(String) 
790       */ 
791      public byte[] toBytecode() 
792              throws NotFoundException, IOException, CannotCompileException { 
793          return getClassPool2().write(getName()); 
794      } 
795   
796      /** 
797       * Writes a class file represented by this <code>CtClass</code> 
798       * object in the current directory. 
799       * Once this method is called, further modifications are not 
800       * possible any more. 
801       * 
802       * <p>This method is equivalent to: 
803       * <ul><pre>this.getClassPool().writeFile(this.getName())</pre></ul> 
804       * 
805       * @see javassist.ClassPool#writeFile(String) 
806       */ 
807      public void writeFile() 
808              throws NotFoundException, IOException, CannotCompileException { 
809          getClassPool2().writeFile(getName()); 
810      } 
811   
812      private ClassPool getClassPool2() throws CannotCompileException { 
813          ClassPool cp = getClassPool(); 
814          if (cp == null) 
815              throw new CannotCompileException( 
816                      "no ClassPool found. not a class?"); 
817          else 
818              return cp; 
819      } 
820   
821      /** 
822       * Converts this class to a class file. 
823       * Once this method is called, further modifications are not 
824       * possible any more. 
825       * 
826       * <p>If this method is used to obtain a byte array representing 
827       * the class file, <code>Translator.onWrite()</code> is never 
828       * called on this class.  <code>ClassPool.write()</code> should 
829       * be used. 
830       * 
831       * <p>This method dose not close the output stream in the end. 
832       * 
833       * @param out       the output stream that a class file is written to. 
834       */ 
835      void toBytecode(DataOutputStream out) 
836              throws CannotCompileException, IOException { 
837          throw new CannotCompileException("not a class"); 
838      } 
839  } 
840