JAVA源码解析(7)-java.beans.IndexedPropertyDescriptor

Jdk版本:1.8.0_131
作者出于学习阶段,如有问题请指正

来自API的解释:IndexedPropertyDescriptor描述了一个像数组一样的属性,并且具有索引的读取和/或索引的写入方法来访问数组的特定元素。 索引属性还可以提供简单的非索引读写方法。 如果这些存在,它们读取和写入由索引读取方法返回的类型的数组。

当前类和PropertyDescriptor的作用很相似,但是PropertyDescriptor提供的只是一个包装readMethod和writeMethod的类,如果当前属性具有两个方法,一个是getName(int n),返回的是数组的第N个名称,还有一个方法是[] getNames,那么这就需要IndexedPropertyDescriptor来进行包装,也可以用于反射来对属性进行包装。

构造器:

IndexedPropertyDescriptor(String propertyName, Class beanClass)
当前构造器构造的writeread方法的名称和PropertyDescriptor一样,都是在属性名前加get/set前缀,并且认为默认的索引writeread方法和普通的非索引方法一致,建议如果能直接构造出四个方法的情况下不要调用此构造器

IndexedPropertyDescriptor(String propertyName, Class beanClass,String readMethodName, String writeMethodName,String indexedReadMethodName, String indexedWriteMethodName)
当前构造器也是用得比较多的一种,直接传入read\write\indexedRead\indexedWrite方法的名字进行构造,构造过程中会将四个方法的名字构造成实际方法:
 public synchronized Method getIndexedReadMethod() {
        Method indexedReadMethod = this.indexedReadMethodRef.get();
        if (indexedReadMethod == null) {
            Class cls = getClass0();
            if (cls == null ||
                (indexedReadMethodName == null && !this.indexedReadMethodRef.isSet())) {
                // the Indexed readMethod was explicitly set to null.
                return null;
            }
            String nextMethodName = Introspector.GET_PREFIX + getBaseName();
            if (indexedReadMethodName == null) {
                Class type = getIndexedPropertyType0();
                if (type == boolean.class || type == null) {
                    indexedReadMethodName = Introspector.IS_PREFIX + getBaseName();
                } else {
                    indexedReadMethodName = nextMethodName;
                }
            }

            Class[] args = { int.class };
            indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
            if ((indexedReadMethod == null) && !indexedReadMethodName.equals(nextMethodName)) {
                // no "is" method, so look for a "get" method.
                indexedReadMethodName = nextMethodName;
                indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
            }
            setIndexedReadMethod0(indexedReadMethod);
        }
        return indexedReadMethod;
    }

IndexedPropertyDescriptor(String propertyName, Method readMethod, Method writeMethod,Method indexedReadMethod, Method indexedWriteMethod)
当前构造器和上个构造器的作用类似,但是和上个构造器相比,少了从方法名构造方法的过程,这个构造器传入的要求是四个方法,而上个构造器会帮忙构造这四种方法

IndexedPropertyDescriptor(Class bean, String base, Method read, Method write, Method readIndexed, Method writeIndexed) throws IntrospectionException {
当前构造器的方法和PropertyDescriptor的一样,将base作为属性名,具体base的处理见上一章对于PropertyDescriptor的解析中base的处理过程

整个类重写了hashCode(1.5开始)和equals(1.4开始)方法,同时提供了合并两个PropertyDescriptor的方法:

 IndexedPropertyDescriptor(PropertyDescriptor x, PropertyDescriptor y) {
        super(x,y);
        if (x instanceof IndexedPropertyDescriptor) {
            IndexedPropertyDescriptor ix = (IndexedPropertyDescriptor)x;
            try {
                Method xr = ix.getIndexedReadMethod();
                if (xr != null) {
                    setIndexedReadMethod(xr);
                }

                Method xw = ix.getIndexedWriteMethod();
                if (xw != null) {
                    setIndexedWriteMethod(xw);
                }
            } catch (IntrospectionException ex) {
                // Should not happen
                throw new AssertionError(ex);
            }
        }
        if (y instanceof IndexedPropertyDescriptor) {
            IndexedPropertyDescriptor iy = (IndexedPropertyDescriptor)y;
            try {
                Method yr = iy.getIndexedReadMethod();
                if (yr != null && yr.getDeclaringClass() == getClass0()) {
                    setIndexedReadMethod(yr);
                }

                Method yw = iy.getIndexedWriteMethod();
                if (yw != null && yw.getDeclaringClass() == getClass0()) {
                    setIndexedWriteMethod(yw);
                }
            } catch (IntrospectionException ex) {
                // Should not happen
                throw new AssertionError(ex);
            }
        }
    }

其他的方法没有太多值得赘述的地方,至于用法,可以见上章的PropertyDescriptor的用法,通过反射先构造,后调用其get\set方法,只是IndexedPropertyDescriptor多了一个索引get和索引set的方法

你可能感兴趣的:(java源码分析)