jdk/src/share/classes/java/lang/reflect/Method.java
changeset 9029 e92fcf58f684
parent 9022 b2e8758b10fd
child 9266 121fb370f179
equal deleted inserted replaced
9028:fa0ffd6693db 9029:e92fcf58f684
    81     // For sharing of MethodAccessors. This branching structure is
    81     // For sharing of MethodAccessors. This branching structure is
    82     // currently only two levels deep (i.e., one root Method and
    82     // currently only two levels deep (i.e., one root Method and
    83     // potentially many Method objects pointing to it.)
    83     // potentially many Method objects pointing to it.)
    84     private Method              root;
    84     private Method              root;
    85 
    85 
    86     // More complicated security check cache needed here than for
       
    87     // Class.newInstance() and Constructor.newInstance()
       
    88     private Class<?> securityCheckCache;
       
    89     private Class<?> securityCheckTargetClassCache;
       
    90 
       
    91    // Generics infrastructure
    86    // Generics infrastructure
    92 
    87 
    93     private String getGenericSignature() {return signature;}
    88     private String getGenericSignature() {return signature;}
    94 
    89 
    95     // Accessor for factory
    90     // Accessor for factory
   400      * {@code abstract}, {@code static}, {@code final},
   395      * {@code abstract}, {@code static}, {@code final},
   401      * {@code synchronized}, {@code native}, {@code strictfp}.
   396      * {@code synchronized}, {@code native}, {@code strictfp}.
   402      */
   397      */
   403     public String toString() {
   398     public String toString() {
   404         try {
   399         try {
   405             StringBuffer sb = new StringBuffer();
   400             StringBuilder sb = new StringBuilder();
   406             int mod = getModifiers() & Modifier.methodModifiers();
   401             int mod = getModifiers() & Modifier.methodModifiers();
   407             if (mod != 0) {
   402             if (mod != 0) {
   408                 sb.append(Modifier.toString(mod) + " ");
   403                 sb.append(Modifier.toString(mod)).append(' ');
   409             }
   404             }
   410             sb.append(Field.getTypeName(getReturnType()) + " ");
   405             sb.append(Field.getTypeName(getReturnType())).append(' ');
   411             sb.append(Field.getTypeName(getDeclaringClass()) + ".");
   406             sb.append(Field.getTypeName(getDeclaringClass())).append('.');
   412             sb.append(getName() + "(");
   407             sb.append(getName()).append('(');
   413             Class<?>[] params = parameterTypes; // avoid clone
   408             Class<?>[] params = parameterTypes; // avoid clone
   414             for (int j = 0; j < params.length; j++) {
   409             for (int j = 0; j < params.length; j++) {
   415                 sb.append(Field.getTypeName(params[j]));
   410                 sb.append(Field.getTypeName(params[j]));
   416                 if (j < (params.length - 1))
   411                 if (j < (params.length - 1))
   417                     sb.append(",");
   412                     sb.append(',');
   418             }
   413             }
   419             sb.append(")");
   414             sb.append(')');
   420             Class<?>[] exceptions = exceptionTypes; // avoid clone
   415             Class<?>[] exceptions = exceptionTypes; // avoid clone
   421             if (exceptions.length > 0) {
   416             if (exceptions.length > 0) {
   422                 sb.append(" throws ");
   417                 sb.append(" throws ");
   423                 for (int k = 0; k < exceptions.length; k++) {
   418                 for (int k = 0; k < exceptions.length; k++) {
   424                     sb.append(exceptions[k].getName());
   419                     sb.append(exceptions[k].getName());
   425                     if (k < (exceptions.length - 1))
   420                     if (k < (exceptions.length - 1))
   426                         sb.append(",");
   421                         sb.append(',');
   427                 }
   422                 }
   428             }
   423             }
   429             return sb.toString();
   424             return sb.toString();
   430         } catch (Exception e) {
   425         } catch (Exception e) {
   431             return "<" + e + ">";
   426             return "<" + e + ">";
   473     public String toGenericString() {
   468     public String toGenericString() {
   474         try {
   469         try {
   475             StringBuilder sb = new StringBuilder();
   470             StringBuilder sb = new StringBuilder();
   476             int mod = getModifiers() & Modifier.methodModifiers();
   471             int mod = getModifiers() & Modifier.methodModifiers();
   477             if (mod != 0) {
   472             if (mod != 0) {
   478                 sb.append(Modifier.toString(mod) + " ");
   473                 sb.append(Modifier.toString(mod)).append(' ');
   479             }
   474             }
   480             TypeVariable<?>[] typeparms = getTypeParameters();
   475             TypeVariable<?>[] typeparms = getTypeParameters();
   481             if (typeparms.length > 0) {
   476             if (typeparms.length > 0) {
   482                 boolean first = true;
   477                 boolean first = true;
   483                 sb.append("<");
   478                 sb.append('<');
   484                 for(TypeVariable<?> typeparm: typeparms) {
   479                 for(TypeVariable<?> typeparm: typeparms) {
   485                     if (!first)
   480                     if (!first)
   486                         sb.append(",");
   481                         sb.append(',');
   487                     // Class objects can't occur here; no need to test
   482                     // Class objects can't occur here; no need to test
   488                     // and call Class.getName().
   483                     // and call Class.getName().
   489                     sb.append(typeparm.toString());
   484                     sb.append(typeparm.toString());
   490                     first = false;
   485                     first = false;
   491                 }
   486                 }
   492                 sb.append("> ");
   487                 sb.append("> ");
   493             }
   488             }
   494 
   489 
   495             Type genRetType = getGenericReturnType();
   490             Type genRetType = getGenericReturnType();
   496             sb.append( ((genRetType instanceof Class<?>)?
   491             sb.append( ((genRetType instanceof Class<?>)?
   497                         Field.getTypeName((Class<?>)genRetType):genRetType.toString())  + " ");
   492                         Field.getTypeName((Class<?>)genRetType):genRetType.toString()))
   498 
   493                     .append(' ');
   499             sb.append(Field.getTypeName(getDeclaringClass()) + ".");
   494 
   500             sb.append(getName() + "(");
   495             sb.append(Field.getTypeName(getDeclaringClass())).append('.');
       
   496             sb.append(getName()).append('(');
   501             Type[] params = getGenericParameterTypes();
   497             Type[] params = getGenericParameterTypes();
   502             for (int j = 0; j < params.length; j++) {
   498             for (int j = 0; j < params.length; j++) {
   503                 String param = (params[j] instanceof Class)?
   499                 String param = (params[j] instanceof Class)?
   504                     Field.getTypeName((Class)params[j]):
   500                     Field.getTypeName((Class)params[j]):
   505                     (params[j].toString());
   501                     (params[j].toString());
   506                 if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
   502                 if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
   507                     param = param.replaceFirst("\\[\\]$", "...");
   503                     param = param.replaceFirst("\\[\\]$", "...");
   508                 sb.append(param);
   504                 sb.append(param);
   509                 if (j < (params.length - 1))
   505                 if (j < (params.length - 1))
   510                     sb.append(",");
   506                     sb.append(',');
   511             }
   507             }
   512             sb.append(")");
   508             sb.append(')');
   513             Type[] exceptions = getGenericExceptionTypes();
   509             Type[] exceptions = getGenericExceptionTypes();
   514             if (exceptions.length > 0) {
   510             if (exceptions.length > 0) {
   515                 sb.append(" throws ");
   511                 sb.append(" throws ");
   516                 for (int k = 0; k < exceptions.length; k++) {
   512                 for (int k = 0; k < exceptions.length; k++) {
   517                     sb.append((exceptions[k] instanceof Class)?
   513                     sb.append((exceptions[k] instanceof Class)?
   518                               ((Class)exceptions[k]).getName():
   514                               ((Class)exceptions[k]).getName():
   519                               exceptions[k].toString());
   515                               exceptions[k].toString());
   520                     if (k < (exceptions.length - 1))
   516                     if (k < (exceptions.length - 1))
   521                         sb.append(",");
   517                         sb.append(',');
   522                 }
   518                 }
   523             }
   519             }
   524             return sb.toString();
   520             return sb.toString();
   525         } catch (Exception e) {
   521         } catch (Exception e) {
   526             return "<" + e + ">";
   522             return "<" + e + ">";
   589            InvocationTargetException
   585            InvocationTargetException
   590     {
   586     {
   591         if (!override) {
   587         if (!override) {
   592             if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
   588             if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
   593                 Class<?> caller = Reflection.getCallerClass(1);
   589                 Class<?> caller = Reflection.getCallerClass(1);
   594                 Class<?> targetClass = ((obj == null || !Modifier.isProtected(modifiers))
   590 
   595                                         ? clazz
   591                 checkAccess(caller, clazz, obj, modifiers);
   596                                         : obj.getClass());
   592             }
   597 
   593         }
   598                 boolean cached;
   594         MethodAccessor ma = methodAccessor;             // read volatile
   599                 synchronized (this) {
   595         if (ma == null) {
   600                     cached = (securityCheckCache == caller)
   596             ma = acquireMethodAccessor();
   601                             && (securityCheckTargetClassCache == targetClass);
   597         }
   602                 }
   598         return ma.invoke(obj, args);
   603                 if (!cached) {
       
   604                     Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
       
   605                     synchronized (this) {
       
   606                         securityCheckCache = caller;
       
   607                         securityCheckTargetClassCache = targetClass;
       
   608                     }
       
   609                 }
       
   610             }
       
   611         }
       
   612         if (methodAccessor == null) acquireMethodAccessor();
       
   613         return methodAccessor.invoke(obj, args);
       
   614     }
   599     }
   615 
   600 
   616     /**
   601     /**
   617      * Returns {@code true} if this method is a bridge
   602      * Returns {@code true} if this method is a bridge
   618      * method; returns {@code false} otherwise.
   603      * method; returns {@code false} otherwise.
   652 
   637 
   653     // NOTE that there is no synchronization used here. It is correct
   638     // NOTE that there is no synchronization used here. It is correct
   654     // (though not efficient) to generate more than one MethodAccessor
   639     // (though not efficient) to generate more than one MethodAccessor
   655     // for a given Method. However, avoiding synchronization will
   640     // for a given Method. However, avoiding synchronization will
   656     // probably make the implementation more scalable.
   641     // probably make the implementation more scalable.
   657     private void acquireMethodAccessor() {
   642     private MethodAccessor acquireMethodAccessor() {
   658         // First check to see if one has been created yet, and take it
   643         // First check to see if one has been created yet, and take it
   659         // if so
   644         // if so
   660         MethodAccessor tmp = null;
   645         MethodAccessor tmp = null;
   661         if (root != null) tmp = root.getMethodAccessor();
   646         if (root != null) tmp = root.getMethodAccessor();
   662         if (tmp != null) {
   647         if (tmp != null) {
   663             methodAccessor = tmp;
   648             methodAccessor = tmp;
   664             return;
   649         } else {
   665         }
   650             // Otherwise fabricate one and propagate it up to the root
   666         // Otherwise fabricate one and propagate it up to the root
   651             tmp = reflectionFactory.newMethodAccessor(this);
   667         tmp = reflectionFactory.newMethodAccessor(this);
   652             setMethodAccessor(tmp);
   668         setMethodAccessor(tmp);
   653         }
       
   654 
       
   655         return tmp;
   669     }
   656     }
   670 
   657 
   671     // Returns MethodAccessor for this Method object, not looking up
   658     // Returns MethodAccessor for this Method object, not looking up
   672     // the chain to the root
   659     // the chain to the root
   673     MethodAccessor getMethodAccessor() {
   660     MethodAccessor getMethodAccessor() {