集册 Java实例教程 通过名称从Java Bean获取属性

通过名称从Java Bean获取属性

欢马劈雪     最近更新时间:2020-01-02 10:19:05

545
通过名称从Java Bean获取属性
/**
 from
* n o w j a v a . c o m - 时代Java 
**/

/*

 * Copyright (c) 2012 EDC

 * 

 * This file is part of Stepping Stone.

 * 

 * Stepping Stone is free software: you can redistribute it and/or modify

 * it under the terms of the GNU General Public License as published by

 * the Free Software Foundation, either version 3 of the License, or

 * (at your option) any later version.

 * 

 * Stepping Stone is distributed in the hope that it will be useful,

 * but WITHOUT ANY WARRANTY; without even the implied warranty of

 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 * GNU General Public License for more details.

 * 

 * You should have received a copy of the GNU General Public License

 * along with Stepping Stone.  If not, see <http://www.gnu.org/licenses/gpl.txt>.

 */

import java.beans.BeanInfo;

import java.beans.IntrospectionException;

import java.beans.Introspector;

import java.beans.PropertyDescriptor;

import java.lang.reflect.Array;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.util.List;

import java.util.regex.Matcher;

import java.util.regex.Pattern;


public class Main{

    public static void main(String[] argv) throws Exception{

        Object bean = "nowjava.com";

        String propName = "nowjava.com";

        System.out.println(getProperty(bean,propName));

    }

    private static final Pattern DOTTED_PATH_SPLITTER = Pattern

            .compile("\\.");
            /** 
             来自 时代Java公众号 - N o w J a  v a . c o m**/

    private static final Pattern SEQUENCE_PATTERN = Pattern

            .compile("^(\\w+)\\[(\\d+)\\]$");

    public static Object getProperty(Object bean, String propName) {

        Object ret = bean;

        String[] parts = DOTTED_PATH_SPLITTER.split(propName);

        try {

            for (String part : parts) {

                Matcher matcher = null;

                if ((matcher = partContainsIndex(part)) != null) {

                    part = matcher.group(1);

                    int idx = Integer.parseInt(matcher.group(2));


                    Method m = determineGetterMethod(ret, part);

                    ret = m.invoke(ret);


                    if (ret instanceof List<?>) {

                        ret = ((List<?>) ret).get(idx);

                    } else {

                        ret = Array.get(ret, idx);

                    }

                } else {

                    Method m = determineGetterMethod(ret, part);

                    ret = m.invoke(ret);

                }

            }

        } catch (IllegalArgumentException e) {

            throw new RuntimeException(e);

        } catch (IllegalAccessException e) {

            throw new RuntimeException(e);

        } catch (InvocationTargetException e) {

            throw new RuntimeException(e);

        } catch (IntrospectionException e) {

            throw new RuntimeException(e);

        }

        return ret;

    }

    private static Matcher partContainsIndex(String part) {

        Matcher m = null;

        if (part.endsWith("]")

                && (m = SEQUENCE_PATTERN.matcher(part)).find()) {

            return m;

        }

        return null;

    }

    public static Method determineGetterMethod(Object bean,

            String beanPropName) throws IntrospectionException {

        return determineAccessorMethod(bean, beanPropName, null,

                AccessorType.GETTER);

    }

    public static Method determineGetterMethod(Object bean,

            String beanPropName, Class<?> paramClass)

            throws IntrospectionException {

        return determineAccessorMethod(bean, beanPropName, paramClass,

                AccessorType.GETTER);

    }

    private static Method determineAccessorMethod(Object bean,

            String beanPropName, Class<?> parameterClass,

            AccessorType accessorType) throws IntrospectionException {


        Method ret = null;

        BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());


        PropertyDescriptor[] propertyDescriptors = beanInfo

                .getPropertyDescriptors();


        PD_ITER: for (PropertyDescriptor pd : propertyDescriptors) {

            if (beanPropName.equals(pd.getName())) {


                // If we do not specify a param type, match by name-only

                if (parameterClass == null) {

                    return accessorType == AccessorType.SETTER ? pd

                            .getWriteMethod() : pd.getReadMethod();

                }


                Method m = null;

                Class<?> methodParamType = null;


                switch (accessorType) {

                case SETTER:

                    m = pd.getWriteMethod();

                    Class<?>[] paramTypes = m.getParameterTypes();

                    if (paramTypes.length == 1) {

                        methodParamType = paramTypes[0];

                    }

                    break;

                case GETTER:

                    m = pd.getReadMethod();


                    if (m != null) {

                        methodParamType = m.getReturnType();

                    }

                    break;

                }


                if (m == null || methodParamType == null) {

                    continue PD_ITER;

                }


                // e.g., Number isAssignableFrom Integer

                if (methodParamType.equals(parameterClass)

                        || methodParamType

                                .isAssignableFrom((parameterClass))) {

                    ret = m;

                    break PD_ITER;

                } else if (methodParamType.isPrimitive()) {

                    if (Number.class.isAssignableFrom(parameterClass)) {

                        if ((Integer.class == parameterClass && Integer.TYPE == methodParamType)

                                || (Short.class == parameterClass && Short.TYPE == methodParamType)

      
展开阅读全文