📄 classpool.java
字号:
/* * Javassist, a Java-bytecode translator toolkit. * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. Alternatively, the contents of this file may be used under * the terms of the GNU Lesser General Public License Version 2.1 or later. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. */package javassist;import java.io.BufferedInputStream;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.lang.reflect.Method;import java.net.URL;import java.security.AccessController;import java.security.PrivilegedActionException;import java.security.PrivilegedExceptionAction;import java.security.ProtectionDomain;import java.util.Hashtable;import java.util.Iterator;import java.util.ArrayList;import javassist.bytecode.Descriptor;/** * A container of <code>CtClass</code> objects. * A <code>CtClass</code> object must be obtained from this object. * If <code>get()</code> is called on this object, * it searches various sources represented by <code>ClassPath</code> * to find a class file and then it creates a <code>CtClass</code> object * representing that class file. The created object is returned to the * caller. * * <p><b>Memory consumption memo:</b> * * <p><code>ClassPool</code> objects hold all the <code>CtClass</code>es * that have been created so that the consistency among modified classes * can be guaranteed. Thus if a large number of <code>CtClass</code>es * are processed, the <code>ClassPool</code> will consume a huge amount * of memory. To avoid this, a <code>ClassPool</code> object * should be recreated, for example, every hundred classes processed. * Note that <code>getDefault()</code> is a singleton factory. * Otherwise, <code>detach()</code> in <code>CtClass</code> should be used * to avoid huge memory consumption. * * <p><b><code>ClassPool</code> hierarchy:</b> * * <p><code>ClassPool</code>s can make a parent-child hierarchy as * <code>java.lang.ClassLoader</code>s. If a <code>ClassPool</code> has * a parent pool, <code>get()</code> first asks the parent pool to find * a class file. Only if the parent could not find the class file, * <code>get()</code> searches the <code>ClassPath</code>s of * the child <code>ClassPool</code>. This search order is reversed if * <code>ClassPath.childFirstLookup</code> is <code>true</code>. * * @see javassist.CtClass * @see javassist.ClassPath */public class ClassPool { // used by toClass(). private static java.lang.reflect.Method defineClass1, defineClass2; static { try { AccessController.doPrivileged(new PrivilegedExceptionAction(){ public Object run() throws Exception{ Class cl = Class.forName("java.lang.ClassLoader"); defineClass1 = cl.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class, int.class }); defineClass2 = cl.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class, int.class, ProtectionDomain.class }); return null; } }); } catch (PrivilegedActionException pae) { throw new RuntimeException("cannot initialize ClassPool", pae.getException()); } } /** * Determines the search order. * * <p>If this field is true, <code>get()</code> first searches the * class path associated to this <code>ClassPool</code> and then * the class path associated with the parent <code>ClassPool</code>. * Otherwise, the class path associated with the parent is searched * first. * * <p>The default value is false. */ public boolean childFirstLookup = false; /** * Turning the automatic pruning on/off. * * <p>If this field is true, <code>CtClass</code> objects are * automatically pruned by default when <code>toBytecode()</code> etc. * are called. The automatic pruning can be turned on/off individually * for each <code>CtClass</code> object. * * <p>The initial value is true. * * @see CtClass#prune() * @see CtClass#stopPruning(boolean) */ public static boolean doPruning = true; /* releaseUnmodifiedClassFile was introduced for avoiding a bug of JBoss AOP. So the value should be true except for JBoss AOP. */ /** * If true, unmodified and not-recently-used class files are * periodically released for saving memory. * * <p>The initial value is true. */ public static boolean releaseUnmodifiedClassFile = true; protected ClassPoolTail source; protected ClassPool parent; protected Hashtable classes; // should be synchronous /** * Table of registered cflow variables. */ private Hashtable cflow = null; // should be synchronous. private static final int INIT_HASH_SIZE = 191; private ArrayList importedPackages; /** * Creates a root class pool. No parent class pool is specified. */ public ClassPool() { this(null); } /** * Creates a root class pool. If <code>useDefaultPath</code> is * true, <code>appendSystemPath()</code> is called. Otherwise, * this constructor is equivalent to the constructor taking no * parameter. * * @param useDefaultPath true if the system search path is * appended. */ public ClassPool(boolean useDefaultPath) { this(null); if (useDefaultPath) appendSystemPath(); } /** * Creates a class pool. * * @param parent the parent of this class pool. If this is a root * class pool, this parameter must be <code>null</code>. * @see javassist.ClassPool#getDefault() */ public ClassPool(ClassPool parent) { this.classes = new Hashtable(INIT_HASH_SIZE); this.source = new ClassPoolTail(); this.parent = parent; if (parent == null) { CtClass[] pt = CtClass.primitiveTypes; for (int i = 0; i < pt.length; ++i) classes.put(pt[i].getName(), pt[i]); } this.cflow = null; clearImportedPackages(); } /** * Returns the default class pool. * The returned object is always identical since this method is * a singleton factory. * * <p>The default class pool searches the system search path, * which usually includes the platform library, extension * libraries, and the search path specified by the * <code>-classpath</code> option or the <code>CLASSPATH</code> * environment variable. * * <p>When this method is called for the first time, the default * class pool is created with the following code snippet: * * <ul><code>ClassPool cp = new ClassPool(); * cp.appendSystemPath(); * </code></ul> * * <p>If the default class pool cannot find any class files, * try <code>ClassClassPath</code> and <code>LoaderClassPath</code>. * * @see ClassClassPath * @see LoaderClassPath */ public static synchronized ClassPool getDefault() { if (defaultPool == null) { defaultPool = new ClassPool(null); defaultPool.appendSystemPath(); } return defaultPool; } private static ClassPool defaultPool = null; /** * Provide a hook so that subclasses can do their own * caching of classes. * * @see #cacheCtClass(String,CtClass,boolean) * @see #removeCached(String) */ protected CtClass getCached(String classname) { return (CtClass)classes.get(classname); } /** * Provides a hook so that subclasses can do their own * caching of classes. * * @see #getCached(String) * @see #removeCached(String,CtClass) */ protected void cacheCtClass(String classname, CtClass c, boolean dynamic) { classes.put(classname, c); } /** * Provide a hook so that subclasses can do their own * caching of classes. * * @see #getCached(String) * @see #cacheCtClass(String,CtClass,boolean) */ protected CtClass removeCached(String classname) { return (CtClass)classes.remove(classname); } /** * Returns the class search path. */ public String toString() { return source.toString(); } /** * Record a package name so that the Javassist compiler searches * the package to resolve a class name. * Don't record the <code>java.lang</code> package, which has * been implicitly recorded by default. * * <p>Note that <code>get()</code> in <code>ClassPool</code> does * not search the recorded package. Only the compiler searches it. * * @param packageName the package name. * It must not include the last '.' (dot). * For example, "java.util" is valid but "java.util." is wrong. * @since 3.1 */ public void importPackage(String packageName) { importedPackages.add(packageName); } /** * Clear all the package names recorded by <code>importPackage()</code>. * The <code>java.lang</code> package is not removed. * * @see #importPackage(String) * @since 3.1 */ public void clearImportedPackages() { importedPackages = new ArrayList(); importedPackages.add("java.lang"); } /** * Returns all the package names recorded by <code>importPackage()</code>. * * @see #importPackage(String) * @since 3.1 */ public Iterator getImportedPackages() { return importedPackages.iterator(); } /** * Records a name that never exists. * For example, a package name can be recorded by this method. * This would improve execution performance
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -