⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxy.java

📁 gcc的组建
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
   * @return the invocation handler, guaranteed non-null.   * @throws IllegalArgumentException if   *         <code>Proxy.isProxyClass(proxy.getClass())</code> returns false.   * @throws NullPointerException if proxy is null   */  public static InvocationHandler getInvocationHandler(Object proxy)  {    if (! isProxyClass(proxy.getClass()))      throw new IllegalArgumentException("not a proxy instance");    return ((Proxy) proxy).h;  }  /**   * Helper class for mapping unique ClassLoader and interface combinations   * to proxy classes.   *   * @author Eric Blake (ebb9@email.byu.edu)   */  private static final class ProxyType  {    /**     * Store the class loader (may be null)     */    final ClassLoader loader;    /**     * Store the interfaces (never null, all elements are interfaces)     */    final Class[] interfaces;    /**     * Construct the helper object.     *     * @param loader the class loader to define the proxy class in; null     *        implies the bootstrap class loader     * @param interfaces an array of interfaces     */    ProxyType(ClassLoader loader, Class[] interfaces)    {      this.loader = loader;      this.interfaces = interfaces;    }    /**     * Calculates the hash code.     *     * @return a combination of the classloader and interfaces hashcodes.     */    public int hashCode()    {      int hash = loader == null ? 0 : loader.hashCode();      for (int i = 0; i < interfaces.length; i++)        hash = hash * 31 + interfaces[i].hashCode();      return hash;    }    /**     * Calculates equality.     *     * @param other object to compare to     * @return true if it is a ProxyType with same data     */    public boolean equals(Object other)    {      ProxyType pt = (ProxyType) other;      if (loader != pt.loader || interfaces.length != pt.interfaces.length)        return false;      for (int i = 0; i < interfaces.length; i++)        if (interfaces[i] != pt.interfaces[i])          return false;      return true;    }  } // class ProxyType  /**   * Helper class which allows hashing of a method name and signature   * without worrying about return type, declaring class, or throws clause,   * and which reduces the maximally common throws clause between two methods   *   * @author Eric Blake (ebb9@email.byu.edu)   */  private static final class ProxySignature  {    /**     * The core signatures which all Proxy instances handle.     */    static final HashMap coreMethods = new HashMap();    static    {      try        {          ProxySignature sig            = new ProxySignature(Object.class                                 .getMethod("equals",                                            new Class[] {Object.class}));          coreMethods.put(sig, sig);          sig = new ProxySignature(Object.class.getMethod("hashCode", null));          coreMethods.put(sig, sig);          sig = new ProxySignature(Object.class.getMethod("toString", null));          coreMethods.put(sig, sig);        }      catch (Exception e)        {          // assert false;          throw (Error) new InternalError("Unexpected: " + e).initCause(e);        }    }    /**     * The underlying Method object, never null     */    final Method method;    /**     * The set of compatible thrown exceptions, may be empty     */    final Set exceptions = new HashSet();    /**     * Construct a signature     *     * @param method the Method this signature is based on, never null     */    ProxySignature(Method method)    {      this.method = method;      Class[] exc = method.getExceptionTypes();      int i = exc.length;      while (--i >= 0)        {          // discard unchecked exceptions          if (Error.class.isAssignableFrom(exc[i])              || RuntimeException.class.isAssignableFrom(exc[i]))            continue;          exceptions.add(exc[i]);        }    }    /**     * Given a method, make sure it's return type is identical     * to this, and adjust this signature's throws clause appropriately     *     * @param other the signature to merge in     * @throws IllegalArgumentException if the return types conflict     */    void checkCompatibility(ProxySignature other)    {      if (method.getReturnType() != other.method.getReturnType())        throw new IllegalArgumentException("incompatible return types: "                                           + method + ", " + other.method);      // if you can think of a more efficient way than this O(n^2) search,      // implement it!      int size1 = exceptions.size();      int size2 = other.exceptions.size();      boolean[] valid1 = new boolean[size1];      boolean[] valid2 = new boolean[size2];      Iterator itr = exceptions.iterator();      int pos = size1;      while (--pos >= 0)        {          Class c1 = (Class) itr.next();          Iterator itr2 = other.exceptions.iterator();          int pos2 = size2;          while (--pos2 >= 0)            {              Class c2 = (Class) itr2.next();              if (c2.isAssignableFrom(c1))                valid1[pos] = true;              if (c1.isAssignableFrom(c2))                valid2[pos2] = true;            }        }      pos = size1;      itr = exceptions.iterator();      while (--pos >= 0)        {          itr.next();          if (! valid1[pos])            itr.remove();        }      pos = size2;      itr = other.exceptions.iterator();      while (--pos >= 0)        {          itr.next();          if (! valid2[pos])            itr.remove();        }      exceptions.addAll(other.exceptions);    }    /**     * Calculates the hash code.     *     * @return a combination of name and parameter types     */    public int hashCode()    {      int hash = method.getName().hashCode();      Class[] types = method.getParameterTypes();      for (int i = 0; i < types.length; i++)        hash = hash * 31 + types[i].hashCode();      return hash;    }    /**     * Calculates equality.     *     * @param other object to compare to     * @return true if it is a ProxySignature with same data     */    public boolean equals(Object other)    {      ProxySignature ps = (ProxySignature) other;      Class[] types1 = method.getParameterTypes();      Class[] types2 = ps.method.getParameterTypes();      if (! method.getName().equals(ps.method.getName())          || types1.length != types2.length)        return false;      int i = types1.length;      while (--i >= 0)        if (types1[i] != types2[i])          return false;      return true;    }  } // class ProxySignature  /**   * A flat representation of all data needed to generate bytecode/instantiate   * a proxy class.  This is basically a struct.   *   * @author Eric Blake (ebb9@email.byu.edu)   */  static final class ProxyData  {    /**     * The package this class is in <b>including the trailing dot</b>     * or an empty string for the unnamed (aka default) package.     */    String pack = "";    /**     * The interfaces this class implements.  Non-null, but possibly empty.     */    Class[] interfaces;    /**     * The Method objects this class must pass as the second argument to     * invoke (also useful for determining what methods this class has).     * Non-null, non-empty (includes at least Object.hashCode, Object.equals,     * and Object.toString).     */    Method[] methods;    /**     * The exceptions that do not need to be wrapped in     * UndeclaredThrowableException. exceptions[i] is the same as, or a     * subset of subclasses, of methods[i].getExceptionTypes(), depending on     * compatible throws clauses with multiple inheritance. It is unspecified     * if these lists include or exclude subclasses of Error and     * RuntimeException, but excluding them is harmless and generates a     * smaller class.     */    Class[][] exceptions;    /**     * For unique id's     */    private static int count;    /**     * The id of this proxy class     */    final int id = count++;    /**     * Construct a ProxyData with uninitialized data members.     */    ProxyData()    {    }    /**     * Return the name of a package (including the trailing dot)     * given the name of a class.     * Returns an empty string if no package.  We use this in preference to     * using Class.getPackage() to avoid problems with ClassLoaders     * that don't set the package.     */    private static String getPackage(Class k)    {      String name = k.getName();      int idx = name.lastIndexOf('.');      return name.substring(0, idx + 1);    }    /**     * Verifies that the arguments are legal, and sets up remaining data     * This should only be called when a class must be generated, as     * it is expensive.     *     * @param pt the ProxyType to convert to ProxyData     * @return the flattened, verified ProxyData structure for use in     *         class generation     * @throws IllegalArgumentException if `interfaces' contains     *         non-interfaces or incompatible combinations, and verify is true     * @throws NullPointerException if interfaces is null or contains null     */    static ProxyData getProxyData(ProxyType pt)    {      Map method_set = (Map) ProxySignature.coreMethods.clone();      boolean in_package = false; // true if we encounter non-public interface      ProxyData data = new ProxyData();      data.interfaces = pt.interfaces;      // if interfaces is too large, we croak later on when the constant      // pool overflows      int i = data.interfaces.length;      while (--i >= 0)        {          Class inter = data.interfaces[i];          if (! inter.isInterface())            throw new IllegalArgumentException("not an interface: " + inter);          try            {              if (Class.forName(inter.getName(), false, pt.loader) != inter)                throw new IllegalArgumentException("not accessible in "                                                   + "classloader: " + inter);            }          catch (ClassNotFoundException e)            {              throw new IllegalArgumentException("not accessible in "                                                 + "classloader: " + inter);            }          if (! Modifier.isPublic(inter.getModifiers()))            if (in_package)              {		String p = getPackage(inter);                if (! data.pack.equals(p))                  throw new IllegalArgumentException("non-public interfaces "                                                     + "from different "                                                     + "packages");              }            else              {                in_package = true;                data.pack = getPackage(inter);              }          for (int j = i-1; j >= 0; j--)            if (data.interfaces[j] == inter)              throw new IllegalArgumentException("duplicate interface: "                                                 + inter);          Method[] methods = inter.getMethods();          int j = methods.length;          while (--j >= 0)            {              ProxySignature sig = new ProxySignature(methods[j]);              ProxySignature old = (ProxySignature) method_set.put(sig, sig);              if (old != null)                sig.checkCompatibility(old);            }        }      i = method_set.size();      data.methods = new Method[i];      data.exceptions = new Class[i][];      Iterator itr = method_set.values().iterator();      while (--i >= 0)        {          ProxySignature sig = (ProxySignature) itr.next();          data.methods[i] = sig.method;          data.exceptions[i] = (Class[]) sig.exceptions            .toArray(new Class[sig.exceptions.size()]);        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -