src/share/classes/java/lang/reflect/Executable.java

Print this page

        

@@ -224,10 +224,22 @@
      * represents
      */
     public abstract Class<?>[] getParameterTypes();
 
     /**
+     * Returns the number of formal parameters (including any
+     * synthetic or synthesized parameters) for the executable
+     * represented by this object.
+     *
+     * @return The number of formal parameters for the executable this
+     * object represents
+     */
+    public int getParameterCount() {
+        throw new AbstractMethodError();
+    }
+
+    /**
      * Returns an array of {@code Type} objects that represent the formal
      * parameter types, in declaration order, of the executable represented by
      * this object. Returns an array of length 0 if the
      * underlying executable takes no parameters.
      *

@@ -257,10 +269,65 @@
         else
             return getParameterTypes();
     }
 
     /**
+     * Returns an array of {@code Parameter} objects that represent
+     * all the parameters to the underlying executable represented by
+     * this object.  Returns an array of length 0 if the executable
+     * has no parameters.
+     *
+     * @return an array of {@code Parameter} objects representing all
+     * the parameters to the executable this object represents
+     */
+    public Parameter[] getParameters() {
+        // TODO: This may eventually need to be guarded by security
+        // mechanisms similar to those in Field, Method, etc.
+        //
+        // Need to copy the cached array to prevent users from messing
+        // with it.  Since parameters are immutable, we can
+        // shallow-copy.
+        return privateGetParameters().clone();
+    }
+
+    private Parameter[] synthesizeAllParams() {
+        final int realparams = getParameterCount();
+        final Parameter[] out = new Parameter[realparams];
+        for (int i = 0; i < realparams; i++)
+            // TODO: is there a way to synthetically derive the
+            // modifiers?  Probably not in the general case, since
+            // we'd have no way of knowing about them, but there
+            // may be specific cases.
+            out[i] = new Parameter("arg" + i, 0, this, i);
+        return out;
+    }
+
+    private Parameter[] privateGetParameters() {
+        // Use tmp to avoid multiple writes to a volatile.
+        Parameter[] tmp = parameters;
+
+        if (tmp == null) {
+
+            // Otherwise, go to the JVM to get them
+            tmp = getParameters0();
+
+            // If we get back nothing, then synthesize parameters
+            if (tmp == null)
+                tmp = synthesizeAllParams();
+
+            parameters = tmp;
+
+        }
+
+        return tmp;
+    }
+
+    private transient volatile Parameter[] parameters;
+
+    private native Parameter[] getParameters0();
+
+    /**
      * Returns an array of {@code Class} objects that represent the
      * types of exceptions declared to be thrown by the underlying
      * executable represented by this object.  Returns an array of
      * length 0 if the executable declares no exceptions in its {@code
      * throws} clause.

@@ -401,6 +468,7 @@
                 getConstantPool(getDeclaringClass()),
                 getDeclaringClass());
         }
         return declaredAnnotations;
     }
+
 }