📄 ctclass.java
字号:
* cc.addField(f, "i + 1") // i + 1. * cc.addField(f, "new Point()"); // a Point object. * </pre></ul> * * <p>Here, the type of variable <code>cc</code> is <code>CtClass</code>. * The type of <code>f</code> is <code>CtField</code>. * * @param init an expression for the initial value. * * @see javassist.CtField.Initializer#byExpr(String) * @see javassist.CtField#CtField(CtField,CtClass) */ public void addField(CtField f, String init) throws CannotCompileException { checkModify(); } /** * Adds a field with an initial value. * * <p>The <code>CtField</code> belonging to another * <code>CtClass</code> cannot be directly added to this class. * Only a field created for this class can be added. * * <p>For example, * * <ul><pre> * CtClass cc = ...; * addField(new CtField(CtClass.intType, "i", cc), * CtField.Initializer.constant(1)); * </pre></ul> * * <p>This code adds an <code>int</code> field named "i". The * initial value of this field is 1. * * @param init specifies the initial value of the field. * * @see javassist.CtField#CtField(CtField,CtClass) */ public void addField(CtField f, CtField.Initializer init) throws CannotCompileException { checkModify(); } /** * Removes a field declared in this class. * * @param f removed field. * @throws NotFoundException if the field is not found. */ public void removeField(CtField f) throws NotFoundException { checkModify(); } /** * Obtains an attribute with the given name. * If that attribute is not found in the class file, this * method returns null. * * <p>This is a convenient method mainly for obtaining * a user-defined attribute. For dealing with attributes, see the * <code>javassist.bytecode</code> package. For example, the following * expression returns all the attributes of a class file. * * <ul><pre> * getClassFile().getAttributes() * </pre></ul> * * @param name attribute name * @see javassist.bytecode.AttributeInfo */ public byte[] getAttribute(String name) { return null; } /** * Adds a named attribute. * An arbitrary data (smaller than 64Kb) can be saved in the class * file. Some attribute name are reserved by the JVM. * The attributes with the non-reserved names are ignored when a * class file is loaded into the JVM. * If there is already an attribute with * the same name, this method substitutes the new one for it. * * <p>This is a convenient method mainly for adding * a user-defined attribute. For dealing with attributes, see the * <code>javassist.bytecode</code> package. For example, the following * expression adds an attribute <code>info</code> to a class file. * * <ul><pre> * getClassFile().addAttribute(info) * </pre></ul> * * @param name attribute name * @param data attribute value * @see javassist.bytecode.AttributeInfo */ public void setAttribute(String name, byte[] data) { checkModify(); } /** * Applies the given converter to all methods and constructors * declared in the class. This method calls <code>instrument()</code> * on every <code>CtMethod</code> and <code>CtConstructor</code> object * in the class. * * @param converter specifies how to modify. */ public void instrument(CodeConverter converter) throws CannotCompileException { checkModify(); } /** * Modifies the bodies of all methods and constructors * declared in the class. This method calls <code>instrument()</code> * on every <code>CtMethod</code> and <code>CtConstructor</code> object * in the class. * * @param editor specifies how to modify. */ public void instrument(ExprEditor editor) throws CannotCompileException { checkModify(); } /** * Converts this class to a <code>java.lang.Class</code> object. * Once this method is called, further modifications are not * allowed any more. * To load the class, this method uses the context class loader * of the current thread. If the program is running on some application * server, the context class loader might be inappropriate to load the * class. * * <p>This method is provided for convenience. If you need more * complex functionality, you should write your own class loader. * * <p>Note: this method calls <code>toClass()</code> * in <code>ClassPool</code>. * * <p><b>Warining:</b> A Class object returned by this method may not * work with a security manager or a signed jar file because a * protection domain is not specified. * * @see #toClass(java.lang.ClassLoader,ProtectionDomain) * @see ClassPool#toClass(CtClass) */ public Class toClass() throws CannotCompileException { return getClassPool().toClass(this); } /** * Converts this class to a <code>java.lang.Class</code> object. * Once this method is called, further modifications are not allowed * any more. * * <p>The class file represented by this <code>CtClass</code> is * loaded by the given class loader to construct a * <code>java.lang.Class</code> object. Since a private method * on the class loader is invoked through the reflection API, * the caller must have permissions to do that. * * <p>An easy way to obtain <code>ProtectionDomain</code> object is * to call <code>getProtectionDomain()</code> * in <code>java.lang.Class</code>. It returns the domain that * the class belongs to. * * <p>This method is provided for convenience. If you need more * complex functionality, you should write your own class loader. * * <p>Note: this method calls <code>toClass()</code> * in <code>ClassPool</code>. * * @param loader the class loader used to load this class. * If it is null, the class loader returned by * {@link ClassPool#getClassLoader()} is used. * @param domain the protection domain that the class belongs to. * If it is null, the default domain created * by <code>java.lang.ClassLoader</code> is used. * @see ClassPool#toClass(CtClass,java.lang.ClassLoader) * @since 3.3 */ public Class toClass(ClassLoader loader, ProtectionDomain domain) throws CannotCompileException { ClassPool cp = getClassPool(); if (loader == null) loader = cp.getClassLoader(); return cp.toClass(this, loader, domain); } /** * Converts this class to a <code>java.lang.Class</code> object. * * <p><b>Warining:</b> A Class object returned by this method may not * work with a security manager or a signed jar file because a * protection domain is not specified. * * @deprecated Replaced by {@link #toClass(ClassLoader,ProtectionDomain)} */ public final Class toClass(ClassLoader loader) throws CannotCompileException { return getClassPool().toClass(this, loader); } /** * Removes this <code>CtClass</code> object from the * <code>ClassPool</code>. * After this method is called, any method cannot be called on the * removed <code>CtClass</code> object. * * <p>If <code>get()</code> in <code>ClassPool</code> is called * with the name of the removed method, * the <code>ClassPool</code> will read the class file again * and constructs another <code>CtClass</code> object representing * the same class. */ public void detach() { ClassPool cp = getClassPool(); CtClass obj = cp.removeCached(getName()); if (obj != this) cp.cacheCtClass(getName(), obj, false); } /** * Disallows (or allows) automatically pruning this <code>CtClass</code> * object. * * <p> * Javassist can automatically prune a <code>CtClass</code> object * when <code>toBytecode()</code> (or <code>toClass()</code>, * <code>writeFile()</code>) is called. * Since a <code>ClassPool</code> holds all instances of <code>CtClass</code> * even after <code>toBytecode()</code> (or <code>toClass()</code>, * <code>writeFile()</code>) is called, pruning may significantly * save memory consumption. * * <p>If <code>ClassPool.doPruning</code> is true, the automatic pruning * is on by default. Otherwise, it is off. * * @param stop disallow pruning if true. Otherwise, allow. * @return the previous status of pruning. true if pruning is already stopped. * * @see #detach() * @see #prune() * @see ClassPool#doPruning */ public boolean stopPruning(boolean stop) { return true; } /** * Discards unnecessary attributes, in particuar, * <code>CodeAttribute</code>s (method bodies) of the class, * to minimize the memory footprint. * After calling this method, the class is read only. * It cannot be modified any more. * Furthermore, <code>toBytecode()</code>, * <code>writeFile()</code>, <code>toClass()</code>, * or <code>instrument()</code> cannot be called. * However, the method names and signatures in the class etc. * are still accessible. * * <p><code>toBytecode()</code>, <code>writeFile()</code>, and * <code>toClass()</code> internally call this method. * * @see #toBytecode() * @see #toClass() * @see #writeFile() * @see #instrument(CodeConverter) * @see #instrument(ExprEditor) * * @see #stopPruning(boolean) */ public void prune() {} /* Called by get() in ClassPool. * CtClassType overrides this method. */ void incGetCounter() {} /** * Converts this class to a class file. * Once this method is called, further modifications are not * possible any more. * * @return the contents of the class file. */ public byte[] toBytecode() throws IOException, CannotCompileException { ByteArrayOutputStream barray = new ByteArrayOutputStream(); DataOutputStream out = new DataOutputStream(barray); try { toBytecode(out); } finally { out.close(); } return barray.toByteArray(); } /** * Writes a class file represented by this <code>CtClass</code> * object in the current directory. * Once this method is called, further modifications are not * possible any more. */ public void writeFile() throws NotFoundException, IOException, CannotCompileException { writeFile("."); } /** * Writes a class file represented by this <code>CtClass</code> * object on a local disk. * Once this method is called, further modifications are not * possible any more. * * @param directoryName it must end without a directory separator. */ public void writeFile(String directoryName) throws CannotCompileException, IOException { String classname = getName(); String filename = directoryName + File.separatorChar + classname.replace('.', File.separatorChar) + ".class"; int pos = filename.lastIndexOf(File.separatorChar); if (pos > 0) { String dir = filename.substring(0, pos); if (!dir.equals(".")) new File(dir).mkdirs(); } DataOutputStream out = new DataOutputStream(new BufferedOutputStream( new DelayedFileOutputStream(filename))); try { toBytecode(out); } finally { out.close(); } } /** * Writes a class file as <code>writeFile()</code> does although this * method does not prune or freeze the class after writing the class * file. Note that, once <code>writeFile()</code> or <code>toBytecode()</code> * is called, it cannot be called again since the class is pruned and frozen. * This method would be useful for debugging. */ public void debugWriteFile() { try { boolean p = stopPruning(true); writeFile(); defrost(); stopPruning(p); } catch (Exception e) { throw new RuntimeException(e); } } static class DelayedFileOutputStream extends OutputStream { private FileOutputStream file; private String filename; DelayedFileOutputStream(String name) { file = null; filename = name; } private void init() throws IOException { if (file == null) file = new FileOutputStream(filename); } public void write(int b) throws IOException { init(); file.write(b); } public void write(byte[] b) throws IOException { init(); file.write(b); } public void write(byte[] b, int off, int len) throws IOException { init(); file.write(b, off, len); } public void flush() throws IOException { init(); file.flush(); } public void close() throws IOException { init(); file.close(); } } /** * Converts this class to a class file. * Once this method is called, further modifications are not * possible any more. * * <p>This method dose not close the output stream in the end. * * @param out the output stream that a class file is written to. */ public void toBytecode(DataOutputStream out) throws CannotCompileException, IOException { throw new CannotCompileException("not a class"); } /** * Makes a unique member name. This method guarantees that * the returned name is not used as a prefix of any methods * or fields visible in this class. * If the returned name is XYZ, then any method or field names * in this class do not start with XYZ. * * @param prefix the prefix of the member name. */ public String makeUniqueName(String prefix) { throw new RuntimeException("not available in " + getName()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -