Jdk版本:1.8.0_131
作者出于学习阶段,如有问题请指正
来自API的解释:IndexedPropertyDescriptor描述了一个像数组一样的属性,并且具有索引的读取和/或索引的写入方法来访问数组的特定元素。 索引属性还可以提供简单的非索引读写方法。 如果这些存在,它们读取和写入由索引读取方法返回的类型的数组。
当前类和PropertyDescriptor的作用很相似,但是PropertyDescriptor提供的只是一个包装readMethod和writeMethod的类,如果当前属性具有两个方法,一个是getName(int n),返回的是数组的第N个名称,还有一个方法是[] getNames,那么这就需要IndexedPropertyDescriptor来进行包装,也可以用于反射来对属性进行包装。
构造器:
IndexedPropertyDescriptor(String propertyName, Class<?> beanClass)
当前构造器构造的write、read方法的名称和PropertyDescriptor一样,都是在属性名前加get/set前缀,并且认为默认的索引write、read方法和普通的非索引方法一致,建议如果能直接构造出四个方法的情况下不要调用此构造器
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的方法