天天看点

Commons Collections学习笔记(四)

BeanMap这个Map类用于把一个javaBean转换为Map,在其中存储了javaBean的各个属性的setXXX方法和getXXX方法,属性的类型。

复制代码

public class BeanMap extends AbstractMap implements Cloneable 

{

    private transient Object bean;//javaBean对象

    private transient HashMap readMethods = new HashMap();//getXXX方法集

    private transient HashMap writeMethods = new HashMap();//setXXX方法集

    private transient HashMap types = new HashMap();//成员变量类型集

    public static final Object[] NULL_ARGUMENTS = {};//空参数集,用于通过reflection调用getXXX方法

    public static HashMap defaultTransformers = new HashMap();//把基本类型映射为transformer类型,后者用于将字符串转换为合适的基本型的包装类

    //默认transformer

    static 

    {

        defaultTransformers.put( Boolean.TYPE, new Transformer() 

        {

                public Object transform( Object input ) 

                {

                    return Boolean.valueOf( input.toString() );

                }

            }

        );

        defaultTransformers.put( Character.TYPE, new Transformer() 

                    return new Character( input.toString().charAt( 0 ) );

        defaultTransformers.put( Byte.TYPE, new Transformer() 

                    return Byte.valueOf( input.toString() );

        defaultTransformers.put( Short.TYPE, new Transformer() 

                    return Short.valueOf( input.toString() );

        defaultTransformers.put( 

            Integer.TYPE, 

            new Transformer() {

                public Object transform( Object input ) {

                    return Integer.valueOf( input.toString() );

        defaultTransformers.put( Long.TYPE, new Transformer() 

                    return Long.valueOf( input.toString() );

        defaultTransformers.put( Float.TYPE, new Transformer() 

                    return Float.valueOf( input.toString() );

        defaultTransformers.put( Double.TYPE, new Transformer() 

                    return Double.valueOf( input.toString() );

    }

    public BeanMap(Object bean) {

        this.bean = bean;

        initialise();

    public Object clone() throws CloneNotSupportedException {

        BeanMap newMap = (BeanMap)super.clone();

        if(bean == null) {//若底层bean不存在,则返回一个复制的空BeanMap,

            return newMap;

        }

        Object newBean = null;            

        Class beanClass = null;

        try {

            beanClass = bean.getClass();//底层bean的Class

            newBean = beanClass.newInstance();//实例化一个新的bean

        } catch (Exception e) {

            // unable to instantiate

            throw new CloneNotSupportedException

                ("Unable to instantiate the underlying bean \"" +

                 beanClass.getName() + "\": " + e);

            newMap.setBean(newBean);

        } catch (Exception exception) {

                ("Unable to set bean in the cloned bean map: " + 

                 exception);

            //复制所有可读写的属性

            Iterator readableKeys = readMethods.keySet().iterator();

            while(readableKeys.hasNext()) {

                Object key = readableKeys.next();//属性名称

                if(getWriteMethod(key) != null) {

                    newMap.put(key, get(key));//放入到新BeanMap中

                ("Unable to copy bean values to cloned bean map: " +

        return newMap;

    public void clear() {

        if(bean == null) return;

            beanClass = bean.getClass();

            bean = beanClass.newInstance();//重新实例化,一切都回到默认状态

        catch (Exception e) {

            throw new UnsupportedOperationException( "Could not create new instance of class: " + beanClass );

    public Object get(Object name) {//获取指定名称属性的值

        if ( bean != null ) {

            Method method = getReadMethod( name );

            if ( method != null ) {

                try {

                    return method.invoke( bean, NULL_ARGUMENTS );

                catch (  IllegalAccessException e ) {

                    logWarn( e );

                catch ( IllegalArgumentException e ) {

                    logWarn(  e );

                catch ( InvocationTargetException e ) {

                catch ( NullPointerException e ) {

        return null;

    public Object put(Object name, Object value) throws IllegalArgumentException, ClassCastException

    {//设置指定名称的属性的值

            Object oldValue = get( name );//原来的值

            Method method = getWriteMethod( name );

            if ( method == null ) {

                throw new IllegalArgumentException( "The bean of type: "+ bean.getClass().getName() + " has no property called: " + name );

            try {

                Object[] arguments = createWriteMethodArguments( method, value );//转换参数

                method.invoke( bean, arguments );//设置新值

                Object newValue = get( name );//获取新设置的值 

                firePropertyChange( name, oldValue, newValue );//fire属性值改变事件

            catch ( InvocationTargetException e ) {

                logInfo( e );

                throw new IllegalArgumentException( e.getMessage() );

            catch ( IllegalAccessException e ) {

            return oldValue;

    public Method getReadMethod(String name) {//获取指定名称属性的getXXX方法

        return (Method) readMethods.get(name);

    public Method getWriteMethod(String name) {//获取指定名称属性的setXXX方法

        return (Method) writeMethods.get(name);

    private void initialise() 

        if(getBean() == null) return;

        Class  beanClass = getBean().getClass();//bean的Class

        try 

            //BeanInfo beanInfo = Introspector.getBeanInfo( bean, null );

            BeanInfo beanInfo = Introspector.getBeanInfo( beanClass );//bean的信息

            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

            if ( propertyDescriptors != null ) 

            {

                for ( int i = 0; i < propertyDescriptors.length; i++ ) 

                    PropertyDescriptor propertyDescriptor = propertyDescriptors[i];

                    if ( propertyDescriptor != null ) 

                    {

                        String name = propertyDescriptor.getName();//属性名称

                        Method readMethod = propertyDescriptor.getReadMethod();//getXXX方法

                        Method writeMethod = propertyDescriptor.getWriteMethod();//setXXX方法

                        Class aType = propertyDescriptor.getPropertyType();//属性类型

                        if ( readMethod != null ) {

                            readMethods.put( name, readMethod );//保存到getXXX集合

                        }

                        if ( writeMethod != null ) {

                            writeMethods.put( name, writeMethod );//保存到setXXX集合

                        types.put( name, aType );//保存属性类型

                    }

        catch ( IntrospectionException e ) {

            logWarn(  e );

    protected static class MyMapEntry extends AbstractMapEntry 

    {//BeanMap使用的Map entry        

        private BeanMap owner;//所属的Map

        protected MyMapEntry( BeanMap owner, Object key, Object value ) {

            super( key, value );

            this.owner = owner;

        public Object setValue(Object value) {

            Object key = getKey();

            Object oldValue = owner.get( key );

            owner.put( key, value );

            Object newValue = owner.get( key );

            super.setValue( newValue );

    protected Object[] createWriteMethodArguments( Method method, Object value ) throws IllegalAccessException, ClassCastException 

    {            

            if ( value != null ) 

                Class[] types = method.getParameterTypes();//setXXX方法的参数类型

                if ( types != null && types.length > 0 ) 

                    Class paramType = types[0];

                    if ( ! paramType.isAssignableFrom( value.getClass() ) ) 

                        value = convertType( paramType, value );//把新参数转换为setXXX方法的参数类型

            Object[] answer = { value };

            return answer;

        catch ( InvocationTargetException e ) {

            logInfo( e );

            throw new IllegalArgumentException( e.getMessage() );

        catch ( InstantiationException e ) {

    protected Object convertType( Class newType, Object value ) 

        throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

        // try call constructor

        Class[] types = { value.getClass() };

        try {//尝试用带一个参数的构造函数进行转换

            Constructor constructor = newType.getConstructor( types );        

            Object[] arguments = { value };

            return constructor.newInstance( arguments );

        catch ( NoSuchMethodException e ) {

            // try using the transformers

            Transformer transformer = getTypeTransformer( newType );//获取可用的transformer

            if ( transformer != null ) {

                return transformer.transform( value );//转换类型

            return value;

    protected Transformer getTypeTransformer( Class aType ) {

        return (Transformer) defaultTransformers.get( aType );

}

本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/12/20/1358910.html,如需转载请自行联系原作者