• java Method


    java  Method

    /*
     * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
     * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     *
     */
    
    package java.lang.reflect;
    
    import sun.reflect.CallerSensitive;
    import sun.reflect.MethodAccessor;
    import sun.reflect.Reflection;
    import sun.reflect.generics.repository.MethodRepository;
    import sun.reflect.generics.factory.CoreReflectionFactory;
    import sun.reflect.generics.factory.GenericsFactory;
    import sun.reflect.generics.scope.MethodScope;
    import sun.reflect.annotation.AnnotationType;
    import sun.reflect.annotation.AnnotationParser;
    import java.lang.annotation.Annotation;
    import java.lang.annotation.AnnotationFormatError;
    import java.nio.ByteBuffer;
    
    /**
     * A {@code Method} provides information about, and access to, a single method
     * on a class or interface.  The reflected method may be a class method
     * or an instance method (including an abstract method).
     *
     * <p>A {@code Method} permits widening conversions to occur when matching the
     * actual parameters to invoke with the underlying method's formal
     * parameters, but it throws an {@code IllegalArgumentException} if a
     * narrowing conversion would occur.
     *
     * @see Member
     * @see java.lang.Class
     * @see java.lang.Class#getMethods()
     * @see java.lang.Class#getMethod(String, Class[])
     * @see java.lang.Class#getDeclaredMethods()
     * @see java.lang.Class#getDeclaredMethod(String, Class[])
     *
     * @author Kenneth Russell
     * @author Nakul Saraiya
     */
    public final class Method extends Executable {
        private Class<?>            clazz;
        private int                 slot;
        // This is guaranteed to be interned by the VM in the 1.4
        // reflection implementation
        private String              name;
        private Class<?>            returnType;
        private Class<?>[]          parameterTypes;
        private Class<?>[]          exceptionTypes;
        private int                 modifiers;
        // Generics and annotations support
        private transient String              signature;
        // generic info repository; lazily initialized
        private transient MethodRepository genericInfo;
        private byte[]              annotations;
        private byte[]              parameterAnnotations;
        private byte[]              annotationDefault;
        private volatile MethodAccessor methodAccessor;
        // For sharing of MethodAccessors. This branching structure is
        // currently only two levels deep (i.e., one root Method and
        // potentially many Method objects pointing to it.)
        //
        // If this branching structure would ever contain cycles, deadlocks can
        // occur in annotation code.
        private Method              root;
    
        // Generics infrastructure
        private String getGenericSignature() {return signature;}
    
        // Accessor for factory
        private GenericsFactory getFactory() {
            // create scope and factory
            return CoreReflectionFactory.make(this, MethodScope.make(this));
        }
    
        // Accessor for generic info repository
        @Override
        MethodRepository getGenericInfo() {
            // lazily initialize repository if necessary
            if (genericInfo == null) {
                // create and cache generic info repository
                genericInfo = MethodRepository.make(getGenericSignature(),
                                                    getFactory());
            }
            return genericInfo; //return cached repository
        }
    
        /**
         * Package-private constructor used by ReflectAccess to enable
         * instantiation of these objects in Java code from the java.lang
         * package via sun.reflect.LangReflectAccess.
         */
        Method(Class<?> declaringClass,
               String name,
               Class<?>[] parameterTypes,
               Class<?> returnType,
               Class<?>[] checkedExceptions,
               int modifiers,
               int slot,
               String signature,
               byte[] annotations,
               byte[] parameterAnnotations,
               byte[] annotationDefault) {
            this.clazz = declaringClass;
            this.name = name;
            this.parameterTypes = parameterTypes;
            this.returnType = returnType;
            this.exceptionTypes = checkedExceptions;
            this.modifiers = modifiers;
            this.slot = slot;
            this.signature = signature;
            this.annotations = annotations;
            this.parameterAnnotations = parameterAnnotations;
            this.annotationDefault = annotationDefault;
        }
    
        /**
         * Package-private routine (exposed to java.lang.Class via
         * ReflectAccess) which returns a copy of this Method. The copy's
         * "root" field points to this Method.
         */
        Method copy() {
            // This routine enables sharing of MethodAccessor objects
            // among Method objects which refer to the same underlying
            // method in the VM. (All of this contortion is only necessary
            // because of the "accessibility" bit in AccessibleObject,
            // which implicitly requires that new java.lang.reflect
            // objects be fabricated for each reflective call on Class
            // objects.)
            if (this.root != null)
                throw new IllegalArgumentException("Can not copy a non-root Method");
    
            Method res = new Method(clazz, name, parameterTypes, returnType,
                                    exceptionTypes, modifiers, slot, signature,
                                    annotations, parameterAnnotations, annotationDefault);
            res.root = this;
            // Might as well eagerly propagate this if already present
            res.methodAccessor = methodAccessor;
            return res;
        }
    
        /**
         * Used by Excecutable for annotation sharing.
         */
        @Override
        Executable getRoot() {
            return root;
        }
    
        @Override
        boolean hasGenericInformation() {
            return (getGenericSignature() != null);
        }
    
        @Override
        byte[] getAnnotationBytes() {
            return annotations;
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        public Class<?> getDeclaringClass() {
            return clazz;
        }
    
        /**
         * Returns the name of the method represented by this {@code Method}
         * object, as a {@code String}.
         */
        @Override
        public String getName() {
            return name;
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        public int getModifiers() {
            return modifiers;
        }
    
        /**
         * {@inheritDoc}
         * @throws GenericSignatureFormatError {@inheritDoc}
         * @since 1.5
         */
        @Override
        @SuppressWarnings({"rawtypes", "unchecked"})
        public TypeVariable<Method>[] getTypeParameters() {
            if (getGenericSignature() != null)
                return (TypeVariable<Method>[])getGenericInfo().getTypeParameters();
            else
                return (TypeVariable<Method>[])new TypeVariable[0];
        }
    
        /**
         * Returns a {@code Class} object that represents the formal return type
         * of the method represented by this {@code Method} object.
         *
         * @return the return type for the method this object represents
         */
        public Class<?> getReturnType() {
            return returnType;
        }
    
        /**
         * Returns a {@code Type} object that represents the formal return
         * type of the method represented by this {@code Method} object.
         *
         * <p>If the return type is a parameterized type,
         * the {@code Type} object returned must accurately reflect
         * the actual type parameters used in the source code.
         *
         * <p>If the return type is a type variable or a parameterized type, it
         * is created. Otherwise, it is resolved.
         *
         * @return  a {@code Type} object that represents the formal return
         *     type of the underlying  method
         * @throws GenericSignatureFormatError
         *     if the generic method signature does not conform to the format
         *     specified in
         *     <cite>The Java&trade; Virtual Machine Specification</cite>
         * @throws TypeNotPresentException if the underlying method's
         *     return type refers to a non-existent type declaration
         * @throws MalformedParameterizedTypeException if the
         *     underlying method's return typed refers to a parameterized
         *     type that cannot be instantiated for any reason
         * @since 1.5
         */
        public Type getGenericReturnType() {
          if (getGenericSignature() != null) {
            return getGenericInfo().getReturnType();
          } else { return getReturnType();}
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        public Class<?>[] getParameterTypes() {
            return parameterTypes.clone();
        }
    
        /**
         * {@inheritDoc}
         * @since 1.8
         */
        public int getParameterCount() { return parameterTypes.length; }
    
    
        /**
         * {@inheritDoc}
         * @throws GenericSignatureFormatError {@inheritDoc}
         * @throws TypeNotPresentException {@inheritDoc}
         * @throws MalformedParameterizedTypeException {@inheritDoc}
         * @since 1.5
         */
        @Override
        public Type[] getGenericParameterTypes() {
            return super.getGenericParameterTypes();
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        public Class<?>[] getExceptionTypes() {
            return exceptionTypes.clone();
        }
    
        /**
         * {@inheritDoc}
         * @throws GenericSignatureFormatError {@inheritDoc}
         * @throws TypeNotPresentException {@inheritDoc}
         * @throws MalformedParameterizedTypeException {@inheritDoc}
         * @since 1.5
         */
        @Override
        public Type[] getGenericExceptionTypes() {
            return super.getGenericExceptionTypes();
        }
    
        /**
         * Compares this {@code Method} against the specified object.  Returns
         * true if the objects are the same.  Two {@code Methods} are the same if
         * they were declared by the same class and have the same name
         * and formal parameter types and return type.
         */
        public boolean equals(Object obj) {
            if (obj != null && obj instanceof Method) {
                Method other = (Method)obj;
                if ((getDeclaringClass() == other.getDeclaringClass())
                    && (getName() == other.getName())) {
                    if (!returnType.equals(other.getReturnType()))
                        return false;
                    return equalParamTypes(parameterTypes, other.parameterTypes);
                }
            }
            return false;
        }
    
        /**
         * Returns a hashcode for this {@code Method}.  The hashcode is computed
         * as the exclusive-or of the hashcodes for the underlying
         * method's declaring class name and the method's name.
         */
        public int hashCode() {
            return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
        }
    
        /**
         * Returns a string describing this {@code Method}.  The string is
         * formatted as the method access modifiers, if any, followed by
         * the method return type, followed by a space, followed by the
         * class declaring the method, followed by a period, followed by
         * the method name, followed by a parenthesized, comma-separated
         * list of the method's formal parameter types. If the method
         * throws checked exceptions, the parameter list is followed by a
         * space, followed by the word throws followed by a
         * comma-separated list of the thrown exception types.
         * For example:
         * <pre>
         *    public boolean java.lang.Object.equals(java.lang.Object)
         * </pre>
         *
         * <p>The access modifiers are placed in canonical order as
         * specified by "The Java Language Specification".  This is
         * {@code public}, {@code protected} or {@code private} first,
         * and then other modifiers in the following order:
         * {@code abstract}, {@code default}, {@code static}, {@code final},
         * {@code synchronized}, {@code native}, {@code strictfp}.
         *
         * @return a string describing this {@code Method}
         *
         * @jls 8.4.3 Method Modifiers
         */
        public String toString() {
            return sharedToString(Modifier.methodModifiers(),
                                  isDefault(),
                                  parameterTypes,
                                  exceptionTypes);
        }
    
        @Override
        void specificToStringHeader(StringBuilder sb) {
            sb.append(getReturnType().getTypeName()).append(' ');
            sb.append(getDeclaringClass().getTypeName()).append('.');
            sb.append(getName());
        }
    
        /**
         * Returns a string describing this {@code Method}, including
         * type parameters.  The string is formatted as the method access
         * modifiers, if any, followed by an angle-bracketed
         * comma-separated list of the method's type parameters, if any,
         * followed by the method's generic return type, followed by a
         * space, followed by the class declaring the method, followed by
         * a period, followed by the method name, followed by a
         * parenthesized, comma-separated list of the method's generic
         * formal parameter types.
         *
         * If this method was declared to take a variable number of
         * arguments, instead of denoting the last parameter as
         * "<tt><i>Type</i>[]</tt>", it is denoted as
         * "<tt><i>Type</i>...</tt>".
         *
         * A space is used to separate access modifiers from one another
         * and from the type parameters or return type.  If there are no
         * type parameters, the type parameter list is elided; if the type
         * parameter list is present, a space separates the list from the
         * class name.  If the method is declared to throw exceptions, the
         * parameter list is followed by a space, followed by the word
         * throws followed by a comma-separated list of the generic thrown
         * exception types.
         *
         * <p>The access modifiers are placed in canonical order as
         * specified by "The Java Language Specification".  This is
         * {@code public}, {@code protected} or {@code private} first,
         * and then other modifiers in the following order:
         * {@code abstract}, {@code default}, {@code static}, {@code final},
         * {@code synchronized}, {@code native}, {@code strictfp}.
         *
         * @return a string describing this {@code Method},
         * include type parameters
         *
         * @since 1.5
         *
         * @jls 8.4.3 Method Modifiers
         */
        @Override
        public String toGenericString() {
            return sharedToGenericString(Modifier.methodModifiers(), isDefault());
        }
    
        @Override
        void specificToGenericStringHeader(StringBuilder sb) {
            Type genRetType = getGenericReturnType();
            sb.append(genRetType.getTypeName()).append(' ');
            sb.append(getDeclaringClass().getTypeName()).append('.');
            sb.append(getName());
        }
    
        /**
         * Invokes the underlying method represented by this {@code Method}
         * object, on the specified object with the specified parameters.
         * Individual parameters are automatically unwrapped to match
         * primitive formal parameters, and both primitive and reference
         * parameters are subject to method invocation conversions as
         * necessary.
         *
         * <p>If the underlying method is static, then the specified {@code obj}
         * argument is ignored. It may be null.
         *
         * <p>If the number of formal parameters required by the underlying method is
         * 0, the supplied {@code args} array may be of length 0 or null.
         *
         * <p>If the underlying method is an instance method, it is invoked
         * using dynamic method lookup as documented in The Java Language
         * Specification, Second Edition, section 15.12.4.4; in particular,
         * overriding based on the runtime type of the target object will occur.
         *
         * <p>If the underlying method is static, the class that declared
         * the method is initialized if it has not already been initialized.
         *
         * <p>If the method completes normally, the value it returns is
         * returned to the caller of invoke; if the value has a primitive
         * type, it is first appropriately wrapped in an object. However,
         * if the value has the type of an array of a primitive type, the
         * elements of the array are <i>not</i> wrapped in objects; in
         * other words, an array of primitive type is returned.  If the
         * underlying method return type is void, the invocation returns
         * null.
         *
         * @param obj  the object the underlying method is invoked from
         * @param args the arguments used for the method call
         * @return the result of dispatching the method represented by
         * this object on {@code obj} with parameters
         * {@code args}
         *
         * @exception IllegalAccessException    if this {@code Method} object
         *              is enforcing Java language access control and the underlying
         *              method is inaccessible.
         * @exception IllegalArgumentException  if the method is an
         *              instance method and the specified object argument
         *              is not an instance of the class or interface
         *              declaring the underlying method (or of a subclass
         *              or implementor thereof); if the number of actual
         *              and formal parameters differ; if an unwrapping
         *              conversion for primitive arguments fails; or if,
         *              after possible unwrapping, a parameter value
         *              cannot be converted to the corresponding formal
         *              parameter type by a method invocation conversion.
         * @exception InvocationTargetException if the underlying method
         *              throws an exception.
         * @exception NullPointerException      if the specified object is null
         *              and the method is an instance method.
         * @exception ExceptionInInitializerError if the initialization
         * provoked by this method fails.
         */
        @CallerSensitive
        public Object invoke(Object obj, Object... args)
            throws IllegalAccessException, IllegalArgumentException,
               InvocationTargetException
        {
            if (!override) {
                if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                    Class<?> caller = Reflection.getCallerClass();
                    checkAccess(caller, clazz, obj, modifiers);
                }
            }
            MethodAccessor ma = methodAccessor;             // read volatile
            if (ma == null) {
                ma = acquireMethodAccessor();
            }
            return ma.invoke(obj, args);
        }
    
        /**
         * Returns {@code true} if this method is a bridge
         * method; returns {@code false} otherwise.
         *
         * @return true if and only if this method is a bridge
         * method as defined by the Java Language Specification.
         * @since 1.5
         */
        public boolean isBridge() {
            return (getModifiers() & Modifier.BRIDGE) != 0;
        }
    
        /**
         * {@inheritDoc}
         * @since 1.5
         */
        @Override
        public boolean isVarArgs() {
            return super.isVarArgs();
        }
    
        /**
         * {@inheritDoc}
         * @jls 13.1 The Form of a Binary
         * @since 1.5
         */
        @Override
        public boolean isSynthetic() {
            return super.isSynthetic();
        }
    
        /**
         * Returns {@code true} if this method is a default
         * method; returns {@code false} otherwise.
         *
         * A default method is a public non-abstract instance method, that
         * is, a non-static method with a body, declared in an interface
         * type.
         *
         * @return true if and only if this method is a default
         * method as defined by the Java Language Specification.
         * @since 1.8
         */
        public boolean isDefault() {
            // Default methods are public non-abstract instance methods
            // declared in an interface.
            return ((getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) ==
                    Modifier.PUBLIC) && getDeclaringClass().isInterface();
        }
    
        // NOTE that there is no synchronization used here. It is correct
        // (though not efficient) to generate more than one MethodAccessor
        // for a given Method. However, avoiding synchronization will
        // probably make the implementation more scalable.
        private MethodAccessor acquireMethodAccessor() {
            // First check to see if one has been created yet, and take it
            // if so
            MethodAccessor tmp = null;
            if (root != null) tmp = root.getMethodAccessor();
            if (tmp != null) {
                methodAccessor = tmp;
            } else {
                // Otherwise fabricate one and propagate it up to the root
                tmp = reflectionFactory.newMethodAccessor(this);
                setMethodAccessor(tmp);
            }
    
            return tmp;
        }
    
        // Returns MethodAccessor for this Method object, not looking up
        // the chain to the root
        MethodAccessor getMethodAccessor() {
            return methodAccessor;
        }
    
        // Sets the MethodAccessor for this Method object and
        // (recursively) its root
        void setMethodAccessor(MethodAccessor accessor) {
            methodAccessor = accessor;
            // Propagate up
            if (root != null) {
                root.setMethodAccessor(accessor);
            }
        }
    
        /**
         * Returns the default value for the annotation member represented by
         * this {@code Method} instance.  If the member is of a primitive type,
         * an instance of the corresponding wrapper type is returned. Returns
         * null if no default is associated with the member, or if the method
         * instance does not represent a declared member of an annotation type.
         *
         * @return the default value for the annotation member represented
         *     by this {@code Method} instance.
         * @throws TypeNotPresentException if the annotation is of type
         *     {@link Class} and no definition can be found for the
         *     default class value.
         * @since  1.5
         */
        public Object getDefaultValue() {
            if  (annotationDefault == null)
                return null;
            Class<?> memberType = AnnotationType.invocationHandlerReturnType(
                getReturnType());
            Object result = AnnotationParser.parseMemberValue(
                memberType, ByteBuffer.wrap(annotationDefault),
                sun.misc.SharedSecrets.getJavaLangAccess().
                    getConstantPool(getDeclaringClass()),
                getDeclaringClass());
            if (result instanceof sun.reflect.annotation.ExceptionProxy)
                throw new AnnotationFormatError("Invalid default: " + this);
            return result;
        }
    
        /**
         * {@inheritDoc}
         * @throws NullPointerException  {@inheritDoc}
         * @since 1.5
         */
        public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
            return super.getAnnotation(annotationClass);
        }
    
        /**
         * {@inheritDoc}
         * @since 1.5
         */
        public Annotation[] getDeclaredAnnotations()  {
            return super.getDeclaredAnnotations();
        }
    
        /**
         * {@inheritDoc}
         * @since 1.5
         */
        @Override
        public Annotation[][] getParameterAnnotations() {
            return sharedGetParameterAnnotations(parameterTypes, parameterAnnotations);
        }
    
        /**
         * {@inheritDoc}
         * @since 1.8
         */
        @Override
        public AnnotatedType getAnnotatedReturnType() {
            return getAnnotatedReturnType0(getGenericReturnType());
        }
    
        @Override
        void handleParameterNumberMismatch(int resultLength, int numParameters) {
            throw new AnnotationFormatError("Parameter annotations don't match number of parameters");
        }
    }

    ###########################

    QQ 3087438119
  • 相关阅读:
    数组中的逆序对
    第一个只出现一次的字符
    丑数
    把数组排成最小的数
    整数中出现1的个数
    连续子数组最大和
    JS之window对象
    JS之递归(例题:猴子吃桃)
    JS中函数的基础知识
    JS数组2(冒泡排列、数组里面查找数据)
  • 原文地址:https://www.cnblogs.com/herd/p/15502184.html
Copyright © 2020-2023  润新知