一、前言
关于spring-beans包中org.springframework.beans.factory.InjectionPoint注入点类,涉及方法参数org.springframework.beans.factory.MethodParameter(详情参见spring-core)、属性java.lang.reflect.Field、java.lang.annotation.Annotation[]数组成员变量,详情参见源码说明。
二、源码说明
1. InjectionPoint类
package org.springframework.beans.factory;@b@@b@import java.lang.annotation.Annotation;@b@import java.lang.reflect.AnnotatedElement;@b@import java.lang.reflect.Field;@b@import java.lang.reflect.Member;@b@import org.springframework.core.MethodParameter;@b@import org.springframework.util.Assert;@b@@b@public class InjectionPoint@b@{@b@ protected MethodParameter methodParameter;@b@ protected Field field;@b@ private volatile Annotation[] fieldAnnotations;@b@@b@ public InjectionPoint(MethodParameter methodParameter)@b@ {@b@ Assert.notNull(methodParameter, "MethodParameter must not be null");@b@ this.methodParameter = methodParameter;@b@ }@b@@b@ public InjectionPoint(Field field)@b@ {@b@ Assert.notNull(field, "Field must not be null");@b@ this.field = field;@b@ }@b@@b@ protected InjectionPoint(InjectionPoint original)@b@ {@b@ this.methodParameter = ((original.methodParameter != null) ? new MethodParameter(original.methodParameter) : null);@b@@b@ this.field = original.field;@b@ this.fieldAnnotations = original.fieldAnnotations;@b@ }@b@@b@ protected InjectionPoint()@b@ {@b@ }@b@@b@ public MethodParameter getMethodParameter()@b@ {@b@ return this.methodParameter;@b@ }@b@@b@ public Field getField()@b@ {@b@ return this.field;@b@ }@b@@b@ public Annotation[] getAnnotations()@b@ {@b@ if (this.field != null) {@b@ if (this.fieldAnnotations == null)@b@ this.fieldAnnotations = this.field.getAnnotations();@b@@b@ return this.fieldAnnotations;@b@ }@b@@b@ return this.methodParameter.getParameterAnnotations();@b@ }@b@@b@ public <A extends Annotation> A getAnnotation(Class<A> annotationType)@b@ {@b@ return ((this.field != null) ? this.field.getAnnotation(annotationType) : this.methodParameter@b@ .getParameterAnnotation(annotationType));@b@ }@b@@b@ public Class<?> getDeclaredType()@b@ {@b@ return ((this.field != null) ? this.field.getType() : this.methodParameter.getParameterType());@b@ }@b@@b@ public Member getMember()@b@ {@b@ return ((this.field != null) ? this.field : this.methodParameter.getMember());@b@ }@b@@b@ public AnnotatedElement getAnnotatedElement()@b@ {@b@ return ((this.field != null) ? this.field : this.methodParameter.getAnnotatedElement());@b@ }@b@@b@ public boolean equals(Object other)@b@ {@b@ if (this == other)@b@ return true;@b@@b@ if (super.getClass() != other.getClass())@b@ return false;@b@@b@ InjectionPoint otherPoint = (InjectionPoint)other;@b@ return ((this.field != null) ? this.field.equals(otherPoint.field) : this.methodParameter@b@ .equals(otherPoint.methodParameter));@b@ }@b@@b@ public int hashCode()@b@ {@b@ return ((this.field != null) ? this.field.hashCode() : this.methodParameter.hashCode());@b@ }@b@@b@ public String toString()@b@ {@b@ return ((this.field != null) ? "field '" + this.field.getName() + "'" : this.methodParameter.toString());@b@ }@b@}
2. MethodParameter类
package org.springframework.core;@b@@b@import java.lang.annotation.Annotation;@b@import java.lang.reflect.AnnotatedElement;@b@import java.lang.reflect.Constructor;@b@import java.lang.reflect.Member;@b@import java.lang.reflect.Method;@b@import java.lang.reflect.ParameterizedType;@b@import java.lang.reflect.Type;@b@import java.util.HashMap;@b@import java.util.Map;@b@import org.springframework.util.Assert;@b@import org.springframework.util.ClassUtils;@b@@b@public class MethodParameter@b@{@b@ private static final Class<?> javaUtilOptionalClass;@b@ private final Method method;@b@ private final Constructor<?> constructor;@b@ private final int parameterIndex;@b@ private int nestingLevel;@b@ Map<Integer, Integer> typeIndexesPerLevel;@b@ private volatile Class<?> containingClass;@b@ private volatile Class<?> parameterType;@b@ private volatile Type genericParameterType;@b@ private volatile Annotation[] parameterAnnotations;@b@ private volatile ParameterNameDiscoverer parameterNameDiscoverer;@b@ private volatile String parameterName;@b@ private volatile MethodParameter nestedMethodParameter;@b@@b@ public MethodParameter(Method method, int parameterIndex)@b@ {@b@ this(method, parameterIndex, 1);@b@ }@b@@b@ public MethodParameter(Method method, int parameterIndex, int nestingLevel)@b@ {@b@ this.nestingLevel = 1;@b@@b@ Assert.notNull(method, "Method must not be null");@b@ this.method = method;@b@ this.parameterIndex = parameterIndex;@b@ this.nestingLevel = nestingLevel;@b@ this.constructor = null;@b@ }@b@@b@ public MethodParameter(Constructor<?> constructor, int parameterIndex)@b@ {@b@ this(constructor, parameterIndex, 1);@b@ }@b@@b@ public MethodParameter(Constructor<?> constructor, int parameterIndex, int nestingLevel)@b@ {@b@ this.nestingLevel = 1;@b@@b@ Assert.notNull(constructor, "Constructor must not be null");@b@ this.constructor = constructor;@b@ this.parameterIndex = parameterIndex;@b@ this.nestingLevel = nestingLevel;@b@ this.method = null;@b@ }@b@@b@ public MethodParameter(MethodParameter original)@b@ {@b@ this.nestingLevel = 1;@b@@b@ Assert.notNull(original, "Original must not be null");@b@ this.method = original.method;@b@ this.constructor = original.constructor;@b@ this.parameterIndex = original.parameterIndex;@b@ this.nestingLevel = original.nestingLevel;@b@ this.typeIndexesPerLevel = original.typeIndexesPerLevel;@b@ this.containingClass = original.containingClass;@b@ this.parameterType = original.parameterType;@b@ this.genericParameterType = original.genericParameterType;@b@ this.parameterAnnotations = original.parameterAnnotations;@b@ this.parameterNameDiscoverer = original.parameterNameDiscoverer;@b@ this.parameterName = original.parameterName;@b@ }@b@@b@ public Method getMethod()@b@ {@b@ return this.method;@b@ }@b@@b@ public Constructor<?> getConstructor()@b@ {@b@ return this.constructor;@b@ }@b@@b@ public Class<?> getDeclaringClass()@b@ {@b@ return getMember().getDeclaringClass();@b@ }@b@@b@ public Member getMember()@b@ {@b@ if (this.method != null) {@b@ return this.method;@b@ }@b@@b@ return this.constructor;@b@ }@b@@b@ public AnnotatedElement getAnnotatedElement()@b@ {@b@ if (this.method != null) {@b@ return this.method;@b@ }@b@@b@ return this.constructor;@b@ }@b@@b@ public int getParameterIndex()@b@ {@b@ return this.parameterIndex;@b@ }@b@@b@ public void increaseNestingLevel()@b@ {@b@ this.nestingLevel += 1;@b@ }@b@@b@ public void decreaseNestingLevel()@b@ {@b@ getTypeIndexesPerLevel().remove(Integer.valueOf(this.nestingLevel));@b@ this.nestingLevel -= 1;@b@ }@b@@b@ public int getNestingLevel()@b@ {@b@ return this.nestingLevel;@b@ }@b@@b@ public void setTypeIndexForCurrentLevel(int typeIndex)@b@ {@b@ getTypeIndexesPerLevel().put(Integer.valueOf(this.nestingLevel), Integer.valueOf(typeIndex));@b@ }@b@@b@ public Integer getTypeIndexForCurrentLevel()@b@ {@b@ return getTypeIndexForLevel(this.nestingLevel);@b@ }@b@@b@ public Integer getTypeIndexForLevel(int nestingLevel)@b@ {@b@ return ((Integer)getTypeIndexesPerLevel().get(Integer.valueOf(nestingLevel)));@b@ }@b@@b@ private Map<Integer, Integer> getTypeIndexesPerLevel()@b@ {@b@ if (this.typeIndexesPerLevel == null)@b@ this.typeIndexesPerLevel = new HashMap(4);@b@@b@ return this.typeIndexesPerLevel;@b@ }@b@@b@ public MethodParameter nested()@b@ {@b@ if (this.nestedMethodParameter != null)@b@ return this.nestedMethodParameter;@b@@b@ MethodParameter nestedParam = clone();@b@ nestedParam.nestingLevel = (this.nestingLevel + 1);@b@ this.nestedMethodParameter = nestedParam;@b@ return nestedParam;@b@ }@b@@b@ public boolean isOptional()@b@ {@b@ return (getParameterType() == javaUtilOptionalClass);@b@ }@b@@b@ public MethodParameter nestedIfOptional()@b@ {@b@ return ((isOptional()) ? nested() : this);@b@ }@b@@b@ void setContainingClass(Class<?> containingClass)@b@ {@b@ this.containingClass = containingClass;@b@ }@b@@b@ public Class<?> getContainingClass() {@b@ return ((this.containingClass != null) ? this.containingClass : getDeclaringClass());@b@ }@b@@b@ void setParameterType(Class<?> parameterType)@b@ {@b@ this.parameterType = parameterType;@b@ }@b@@b@ public Class<?> getParameterType()@b@ {@b@ Class paramType = this.parameterType;@b@ if (paramType == null) {@b@ if (this.parameterIndex < 0) {@b@ Method method = getMethod();@b@ paramType = (method != null) ? method.getReturnType() : Void.TYPE;@b@ }@b@ else@b@ {@b@ paramType = (this.method != null) ? this.method@b@ .getParameterTypes()[this.parameterIndex] : this.constructor@b@ .getParameterTypes()[this.parameterIndex];@b@ }@b@ this.parameterType = paramType;@b@ }@b@ return paramType;@b@ }@b@@b@ public Type getGenericParameterType()@b@ {@b@ Type paramType = this.genericParameterType;@b@ if (paramType == null) {@b@ if (this.parameterIndex < 0) {@b@ Method method = getMethod();@b@ paramType = (method != null) ? method.getGenericReturnType() : Void.TYPE;@b@ }@b@ else@b@ {@b@ paramType = (this.method != null) ? this.method@b@ .getGenericParameterTypes()[this.parameterIndex] : this.constructor@b@ .getGenericParameterTypes()[this.parameterIndex];@b@ }@b@ this.genericParameterType = paramType;@b@ }@b@ return paramType;@b@ }@b@@b@ public Class<?> getNestedParameterType()@b@ {@b@ if (this.nestingLevel > 1) {@b@ Type type = getGenericParameterType();@b@ for (int i = 2; i <= this.nestingLevel; ++i)@b@ if (type instanceof ParameterizedType) {@b@ Type[] args = ((ParameterizedType)type).getActualTypeArguments();@b@ Integer index = getTypeIndexForLevel(i);@b@ type = args[(args.length - 1)];@b@ }@b@@b@@b@ if (type instanceof Class)@b@ return ((Class)type);@b@@b@ if (type instanceof ParameterizedType) {@b@ Type arg = ((ParameterizedType)type).getRawType();@b@ if (arg instanceof Class)@b@ return ((Class)arg);@b@ }@b@@b@ return Object.class;@b@ }@b@@b@ return getParameterType();@b@ }@b@@b@ public Type getNestedGenericParameterType()@b@ {@b@ if (this.nestingLevel > 1) {@b@ Type type = getGenericParameterType();@b@ for (int i = 2; i <= this.nestingLevel; ++i)@b@ if (type instanceof ParameterizedType) {@b@ Type[] args = ((ParameterizedType)type).getActualTypeArguments();@b@ Integer index = getTypeIndexForLevel(i);@b@ type = args[(args.length - 1)];@b@ }@b@@b@ return type;@b@ }@b@@b@ return getGenericParameterType();@b@ }@b@@b@ public Annotation[] getMethodAnnotations()@b@ {@b@ return adaptAnnotationArray(getAnnotatedElement().getAnnotations());@b@ }@b@@b@ public <A extends Annotation> A getMethodAnnotation(Class<A> annotationType)@b@ {@b@ return adaptAnnotation(getAnnotatedElement().getAnnotation(annotationType));@b@ }@b@@b@ public <A extends Annotation> boolean hasMethodAnnotation(Class<A> annotationType)@b@ {@b@ return getAnnotatedElement().isAnnotationPresent(annotationType);@b@ }@b@@b@ public Annotation[] getParameterAnnotations()@b@ {@b@ if (this.parameterAnnotations == null)@b@ {@b@ Annotation[][] annotationArray = (this.method != null) ? this.method@b@ .getParameterAnnotations() : this.constructor.getParameterAnnotations();@b@ if ((this.parameterIndex >= 0) && (this.parameterIndex < annotationArray.length)) {@b@ this.parameterAnnotations = adaptAnnotationArray(annotationArray[this.parameterIndex]);@b@ }@b@ else@b@ this.parameterAnnotations = new Annotation[0];@b@ }@b@@b@ return this.parameterAnnotations;@b@ }@b@@b@ public boolean hasParameterAnnotations()@b@ {@b@ return (getParameterAnnotations().length != 0);@b@ }@b@@b@ public <A extends Annotation> A getParameterAnnotation(Class<A> annotationType)@b@ {@b@ Annotation[] anns = getParameterAnnotations();@b@ Annotation[] arrayOfAnnotation1 = anns; int i = arrayOfAnnotation1.length; for (int j = 0; j < i; ++j) { Annotation ann = arrayOfAnnotation1[j];@b@ if (annotationType.isInstance(ann))@b@ return ann;@b@ }@b@@b@ return null;@b@ }@b@@b@ public <A extends Annotation> boolean hasParameterAnnotation(Class<A> annotationType)@b@ {@b@ return (getParameterAnnotation(annotationType) != null);@b@ }@b@@b@ public void initParameterNameDiscovery(ParameterNameDiscoverer parameterNameDiscoverer)@b@ {@b@ this.parameterNameDiscoverer = parameterNameDiscoverer;@b@ }@b@@b@ public String getParameterName()@b@ {@b@ ParameterNameDiscoverer discoverer = this.parameterNameDiscoverer;@b@ if (discoverer != null)@b@ {@b@ String[] parameterNames = (this.method != null) ? discoverer@b@ .getParameterNames(this.method)@b@ : discoverer.getParameterNames(this.constructor);@b@ if (parameterNames != null)@b@ this.parameterName = parameterNames[this.parameterIndex];@b@@b@ this.parameterNameDiscoverer = null;@b@ }@b@ return this.parameterName;@b@ }@b@@b@ protected <A extends Annotation> A adaptAnnotation(A annotation)@b@ {@b@ return annotation;@b@ }@b@@b@ protected Annotation[] adaptAnnotationArray(Annotation[] annotations)@b@ {@b@ return annotations;@b@ }@b@@b@ public boolean equals(Object other)@b@ {@b@ if (this == other)@b@ return true;@b@@b@ if (!(other instanceof MethodParameter))@b@ return false;@b@@b@ MethodParameter otherParam = (MethodParameter)other;@b@ return ((this.parameterIndex == otherParam.parameterIndex) && (getMember().equals(otherParam.getMember())));@b@ }@b@@b@ public int hashCode()@b@ {@b@ return (getMember().hashCode() * 31 + this.parameterIndex);@b@ }@b@@b@ public String toString()@b@ {@b@ return new StringBuilder().append((this.method != null) ? new StringBuilder().append("method '").append(this.method.getName()).append("'").toString() : "constructor").append(" parameter ").append(this.parameterIndex).toString();@b@ }@b@@b@ public MethodParameter clone()@b@ {@b@ return new MethodParameter(this);@b@ }@b@@b@ public static MethodParameter forMethodOrConstructor(Object methodOrConstructor, int parameterIndex)@b@ {@b@ if (methodOrConstructor instanceof Method)@b@ return new MethodParameter((Method)methodOrConstructor, parameterIndex);@b@@b@ if (methodOrConstructor instanceof Constructor) {@b@ return new MethodParameter((Constructor)methodOrConstructor, parameterIndex);@b@ }@b@@b@ throw new IllegalArgumentException(new StringBuilder().append("Given object [").append(methodOrConstructor).append("] is neither a Method nor a Constructor").toString());@b@ }@b@@b@ static@b@ {@b@ Class clazz;@b@ try@b@ {@b@ clazz = ClassUtils.forName("java.util.Optional", MethodParameter.class.getClassLoader());@b@ }@b@ catch (ClassNotFoundException ex)@b@ {@b@ clazz = null;@b@ }@b@ javaUtilOptionalClass = clazz;@b@ }@b@}
3. DependencyDescriptor继承InjectionPoint用法
package org.springframework.beans.factory.config;@b@@b@import java.io.IOException;@b@import java.io.ObjectInputStream;@b@import java.io.Serializable;@b@import java.lang.reflect.Constructor;@b@import java.lang.reflect.Field;@b@import java.lang.reflect.Method;@b@import java.lang.reflect.ParameterizedType;@b@import java.lang.reflect.Type;@b@import java.util.Map;@b@import org.springframework.beans.BeansException;@b@import org.springframework.beans.factory.BeanFactory;@b@import org.springframework.beans.factory.InjectionPoint;@b@import org.springframework.beans.factory.NoUniqueBeanDefinitionException;@b@import org.springframework.core.GenericCollectionTypeResolver;@b@import org.springframework.core.GenericTypeResolver;@b@import org.springframework.core.MethodParameter;@b@import org.springframework.core.ParameterNameDiscoverer;@b@import org.springframework.core.ResolvableType;@b@@b@public class DependencyDescriptor extends InjectionPoint@b@ implements Serializable@b@{@b@ private final Class<?> declaringClass;@b@ private String methodName;@b@ private Class<?>[] parameterTypes;@b@ private int parameterIndex;@b@ private String fieldName;@b@ private final boolean required;@b@ private final boolean eager;@b@ private int nestingLevel;@b@ private Class<?> containingClass;@b@ private volatile ResolvableType resolvableType;@b@@b@ public DependencyDescriptor(MethodParameter methodParameter, boolean required)@b@ {@b@ this(methodParameter, required, true);@b@ }@b@@b@ public DependencyDescriptor(MethodParameter methodParameter, boolean required, boolean eager)@b@ {@b@ super(methodParameter);@b@@b@ this.nestingLevel = 1;@b@@b@ this.declaringClass = methodParameter.getDeclaringClass();@b@ if (this.methodParameter.getMethod() != null) {@b@ this.methodName = methodParameter.getMethod().getName();@b@ this.parameterTypes = methodParameter.getMethod().getParameterTypes();@b@ }@b@ else {@b@ this.parameterTypes = methodParameter.getConstructor().getParameterTypes();@b@ }@b@ this.parameterIndex = methodParameter.getParameterIndex();@b@ this.containingClass = methodParameter.getContainingClass();@b@ this.required = required;@b@ this.eager = eager;@b@ }@b@@b@ public DependencyDescriptor(Field field, boolean required)@b@ {@b@ this(field, required, true);@b@ }@b@@b@ public DependencyDescriptor(Field field, boolean required, boolean eager)@b@ {@b@ super(field);@b@@b@ this.nestingLevel = 1;@b@@b@ this.declaringClass = field.getDeclaringClass();@b@ this.fieldName = field.getName();@b@ this.required = required;@b@ this.eager = eager;@b@ }@b@@b@ public DependencyDescriptor(DependencyDescriptor original)@b@ {@b@ super(original);@b@@b@ this.nestingLevel = 1;@b@@b@ this.declaringClass = original.declaringClass;@b@ this.methodName = original.methodName;@b@ this.parameterTypes = original.parameterTypes;@b@ this.parameterIndex = original.parameterIndex;@b@ this.fieldName = original.fieldName;@b@ this.containingClass = original.containingClass;@b@ this.required = original.required;@b@ this.eager = original.eager;@b@ this.nestingLevel = original.nestingLevel;@b@ }@b@@b@ public boolean isRequired()@b@ {@b@ return this.required;@b@ }@b@@b@ public boolean isEager()@b@ {@b@ return this.eager;@b@ }@b@@b@ public Object resolveNotUnique(Class<?> type, Map<String, Object> matchingBeans)@b@ throws BeansException@b@ {@b@ throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());@b@ }@b@@b@ public Object resolveShortcut(BeanFactory beanFactory)@b@ throws BeansException@b@ {@b@ return null;@b@ }@b@@b@ public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)@b@ throws BeansException@b@ {@b@ return beanFactory.getBean(beanName, requiredType);@b@ }@b@@b@ public void increaseNestingLevel()@b@ {@b@ this.nestingLevel += 1;@b@ this.resolvableType = null;@b@ if (this.methodParameter != null)@b@ this.methodParameter.increaseNestingLevel();@b@ }@b@@b@ public void setContainingClass(Class<?> containingClass)@b@ {@b@ this.containingClass = containingClass;@b@ this.resolvableType = null;@b@ if (this.methodParameter != null)@b@ GenericTypeResolver.resolveParameterType(this.methodParameter, containingClass);@b@ }@b@@b@ public ResolvableType getResolvableType()@b@ {@b@ ResolvableType resolvableType = this.resolvableType;@b@ if (resolvableType == null)@b@ {@b@ resolvableType = (this.field != null) ? @b@ ResolvableType.forField(this.field, this.nestingLevel, this.containingClass)@b@ : @b@ ResolvableType.forMethodParameter(this.methodParameter);@b@@b@ this.resolvableType = resolvableType;@b@ }@b@ return resolvableType;@b@ }@b@@b@ public boolean fallbackMatchAllowed()@b@ {@b@ return false;@b@ }@b@@b@ public DependencyDescriptor forFallbackMatch()@b@ {@b@ return new DependencyDescriptor(this, this)@b@ {@b@ public boolean fallbackMatchAllowed() {@b@ return true;@b@ }@b@ };@b@ }@b@@b@ public void initParameterNameDiscovery(ParameterNameDiscoverer parameterNameDiscoverer)@b@ {@b@ if (this.methodParameter != null)@b@ this.methodParameter.initParameterNameDiscovery(parameterNameDiscoverer);@b@ }@b@@b@ public String getDependencyName()@b@ {@b@ return ((this.field != null) ? this.field.getName() : this.methodParameter.getParameterName());@b@ }@b@@b@ public Class<?> getDependencyType()@b@ {@b@ if (this.field != null) {@b@ if (this.nestingLevel > 1) {@b@ Type type = this.field.getGenericType();@b@ for (int i = 2; i <= this.nestingLevel; ++i)@b@ if (type instanceof ParameterizedType) {@b@ Type[] args = ((ParameterizedType)type).getActualTypeArguments();@b@ type = args[(args.length - 1)];@b@ }@b@@b@@b@ if (type instanceof Class)@b@ return ((Class)type);@b@@b@ if (type instanceof ParameterizedType) {@b@ Type arg = ((ParameterizedType)type).getRawType();@b@ if (arg instanceof Class)@b@ return ((Class)arg);@b@ }@b@@b@ return Object.class;@b@ }@b@@b@ return this.field.getType();@b@ }@b@@b@ return this.methodParameter.getNestedParameterType();@b@ }@b@@b@ @Deprecated@b@ public Class<?> getCollectionType()@b@ {@b@ return ((this.field != null) ? @b@ GenericCollectionTypeResolver.getCollectionFieldType(this.field, this.nestingLevel)@b@ : @b@ GenericCollectionTypeResolver.getCollectionParameterType(this.methodParameter));@b@ }@b@@b@ @Deprecated@b@ public Class<?> getMapKeyType()@b@ {@b@ return ((this.field != null) ? @b@ GenericCollectionTypeResolver.getMapKeyFieldType(this.field, this.nestingLevel)@b@ : @b@ GenericCollectionTypeResolver.getMapKeyParameterType(this.methodParameter));@b@ }@b@@b@ @Deprecated@b@ public Class<?> getMapValueType()@b@ {@b@ return ((this.field != null) ? @b@ GenericCollectionTypeResolver.getMapValueFieldType(this.field, this.nestingLevel)@b@ : @b@ GenericCollectionTypeResolver.getMapValueParameterType(this.methodParameter));@b@ }@b@@b@ public boolean equals(Object other)@b@ {@b@ if (this == other)@b@ return true;@b@@b@ if (!(super.equals(other)))@b@ return false;@b@@b@ DependencyDescriptor otherDesc = (DependencyDescriptor)other;@b@ return ((this.required == otherDesc.required) && (this.eager == otherDesc.eager) && (this.nestingLevel == otherDesc.nestingLevel) && (this.containingClass == otherDesc.containingClass));@b@ }@b@@b@ private void readObject(ObjectInputStream ois)@b@ throws IOException, ClassNotFoundException@b@ {@b@ int i;@b@ ois.defaultReadObject();@b@ try@b@ {@b@ if (this.fieldName != null) {@b@ this.field = this.declaringClass.getDeclaredField(this.fieldName);@b@ }@b@ else {@b@ if (this.methodName != null) {@b@ this.methodParameter = @b@ new MethodParameter(this.declaringClass@b@ .getDeclaredMethod(this.methodName, this.parameterTypes), @b@ this.parameterIndex);@b@ }@b@ else@b@ this.methodParameter = @b@ new MethodParameter(this.declaringClass@b@ .getDeclaredConstructor(this.parameterTypes), @b@ this.parameterIndex);@b@@b@ for (i = 1; i < this.nestingLevel; ++i)@b@ this.methodParameter.increaseNestingLevel();@b@ }@b@ }@b@ catch (Throwable ex)@b@ {@b@ throw new IllegalStateException("Could not find original class structure", ex);@b@ }@b@ }@b@}