jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java
changeset 26467 d69abed3a07d
parent 25859 3317bb8137f4
child 29986 97167d851fc4
equal deleted inserted replaced
26466:3bbb6a284bd4 26467:d69abed3a07d
    31 import sun.invoke.WrapperInstance;
    31 import sun.invoke.WrapperInstance;
    32 import java.util.ArrayList;
    32 import java.util.ArrayList;
    33 import sun.reflect.CallerSensitive;
    33 import sun.reflect.CallerSensitive;
    34 import sun.reflect.Reflection;
    34 import sun.reflect.Reflection;
    35 import sun.reflect.misc.ReflectUtil;
    35 import sun.reflect.misc.ReflectUtil;
       
    36 import static java.lang.invoke.MethodHandleStatics.*;
    36 
    37 
    37 /**
    38 /**
    38  * This class consists exclusively of static methods that help adapt
    39  * This class consists exclusively of static methods that help adapt
    39  * method handles to other JVM types, such as interfaces.
    40  * method handles to other JVM types, such as interfaces.
    40  */
    41  */
   146     //
   147     //
   147     @CallerSensitive
   148     @CallerSensitive
   148     public static
   149     public static
   149     <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
   150     <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
   150         if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
   151         if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
   151             throw new IllegalArgumentException("not a public interface: "+intfc.getName());
   152             throw newIllegalArgumentException("not a public interface", intfc.getName());
   152         final MethodHandle mh;
   153         final MethodHandle mh;
   153         if (System.getSecurityManager() != null) {
   154         if (System.getSecurityManager() != null) {
   154             final Class<?> caller = Reflection.getCallerClass();
   155             final Class<?> caller = Reflection.getCallerClass();
   155             final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
   156             final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
   156             ReflectUtil.checkProxyPackageAccess(ccl, intfc);
   157             ReflectUtil.checkProxyPackageAccess(ccl, intfc);
   163             ClassLoader cl = Thread.currentThread().getContextClassLoader(); // avoid use of BCP
   164             ClassLoader cl = Thread.currentThread().getContextClassLoader(); // avoid use of BCP
   164             proxyLoader = cl != null ? cl : ClassLoader.getSystemClassLoader();
   165             proxyLoader = cl != null ? cl : ClassLoader.getSystemClassLoader();
   165         }
   166         }
   166         final Method[] methods = getSingleNameMethods(intfc);
   167         final Method[] methods = getSingleNameMethods(intfc);
   167         if (methods == null)
   168         if (methods == null)
   168             throw new IllegalArgumentException("not a single-method interface: "+intfc.getName());
   169             throw newIllegalArgumentException("not a single-method interface", intfc.getName());
   169         final MethodHandle[] vaTargets = new MethodHandle[methods.length];
   170         final MethodHandle[] vaTargets = new MethodHandle[methods.length];
   170         for (int i = 0; i < methods.length; i++) {
   171         for (int i = 0; i < methods.length; i++) {
   171             Method sm = methods[i];
   172             Method sm = methods[i];
   172             MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes());
   173             MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes());
   173             MethodHandle checkTarget = mh.asType(smMT);  // make throw WMT
   174             MethodHandle checkTarget = mh.asType(smMT);  // make throw WMT
   187                     }
   188                     }
   188                     if (method.getDeclaringClass() == WrapperInstance.class)
   189                     if (method.getDeclaringClass() == WrapperInstance.class)
   189                         return getArg(method.getName());
   190                         return getArg(method.getName());
   190                     if (isObjectMethod(method))
   191                     if (isObjectMethod(method))
   191                         return callObjectMethod(proxy, method, args);
   192                         return callObjectMethod(proxy, method, args);
   192                     throw new InternalError("bad proxy method: "+method);
   193                     throw newInternalError("bad proxy method: "+method);
   193                 }
   194                 }
   194             };
   195             };
   195 
   196 
   196         final Object proxy;
   197         final Object proxy;
   197         if (System.getSecurityManager() != null) {
   198         if (System.getSecurityManager() != null) {
   238         try {
   239         try {
   239             if (x != null)
   240             if (x != null)
   240                 return (WrapperInstance) x;
   241                 return (WrapperInstance) x;
   241         } catch (ClassCastException ex) {
   242         } catch (ClassCastException ex) {
   242         }
   243         }
   243         throw new IllegalArgumentException("not a wrapper instance");
   244         throw newIllegalArgumentException("not a wrapper instance");
   244     }
   245     }
   245 
   246 
   246     /**
   247     /**
   247      * Produces or recovers a target method handle which is behaviorally
   248      * Produces or recovers a target method handle which is behaviorally
   248      * equivalent to the unique method of this wrapper instance.
   249      * equivalent to the unique method of this wrapper instance.