集册 Java实例教程 从指定的对象获取指定的属性。

从指定的对象获取指定的属性。

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

624
提示:您可在线编辑运行本教程的实例 - 运行实例,去试试!
从指定的对象获取指定的属性。

/*

 * The contents of this file are subject to the Sapient Public License

 * Version 1.0 (the "License"); you may not use this file except in compliance

 * with the License. You may obtain a copy of the License at

 * http://carbon.sf.net/License.html.

 *

 * Software distributed under the License is distributed on an "AS IS" basis,

 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for

 * the specific language governing rights and limitations under the License.

 *

 * The Original Code is The Carbon Component Framework.

 *

 * The Initial Developer of the Original Code is Sapient Corporation

 *

 * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.

 */

//package com.nowjava;

import java.beans.BeanInfo;// 来 自 时 代 J a v a - nowjava.com

import java.beans.IntrospectionException;

import java.beans.Introspector;

import java.beans.PropertyDescriptor;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.util.StringTokenizer;


public class Main {

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

        Object bean = "nowjava.com";

        String propertyNames = "nowjava.com";

        System.out.println(getObjectAttribute(bean, propertyNames));

    }


    /**

     * String used to separate multiple properties inside of embedded

     * beans.

     */

    private static final String PROPERTY_SEPARATOR = ".";
    /**
     from
    * n o w  j a v a  . c o m 
    **/

    /**

     * an empty object array used for null parameter method reflection

     */

    private static Object[] NO_ARGUMENTS_ARRAY = new Object[] {};


    /**

     * <p>Gets the specified attribute from the specified object.  For example,

     * <code>getObjectAttribute(o, "address.line1")</code> will return

     * the result of calling <code>o.getAddress().getLine1()</code>.<p>

     *

     * <p>The attribute specified may contain as many levels as you like. If at

     * any time a null reference is acquired by calling one of the successive

     * getter methods, then the return value from this method is also null.</p>

     *

     * <p>When reading from a boolean property the underlying bean introspector

     * first looks for an is&lt;Property&gt; read method, not finding one it will

     * still look for a get&lt;Property&gt; read method.  Not finding either, the

     * property is considered write-only.</p>

     *

     * @param bean the bean to set the property on

     * @param propertyNames the name of the propertie(s) to retrieve.  If this is

     *        null or the empty string, then <code>bean</code> will be returned.

     * @return the object value of the bean attribute

     *

     * @throws PropertyNotFoundException indicates the the given property

     *         could not be found on the bean

     * @throws NoSuchMethodException Not thrown

     * @throws InvocationTargetException if a specified getter method throws an

     *   exception.

     * @throws IllegalAccessException if a getter method is

     *   not public or property is write-only.

     */

    public static Object getObjectAttribute(Object bean,

            String propertyNames) throws NoSuchMethodException,

            InvocationTargetException, IllegalAccessException {


        Object result = bean;


        StringTokenizer propertyTokenizer = new StringTokenizer(

                propertyNames, PROPERTY_SEPARATOR);


        // Run through the tokens, calling get methods and

        // replacing result with the new object each time.

        // If the result equals null, then simply return null.

        while (propertyTokenizer.hasMoreElements() && result != null) {

            Class resultClass = result.getClass();

            String currentPropertyName = propertyTokenizer.nextToken();


            PropertyDescriptor propertyDescriptor = getPropertyDescriptor(

                    currentPropertyName, resultClass);


            Method readMethod = propertyDescriptor.getReadMethod();

            if (readMethod == null) {

                throw new IllegalAccessException(

                        "User is attempting to "

                                + "read from a property that has no read method.  "

                                + " This is likely a write-only bean property.  Caused "

                                + "by property [" + currentPropertyName

                                + "] on class [" + resultClass + "]");

            }


            result = readMethod.invoke(result, NO_ARGUMENTS_ARRAY);

        }


        return result;

    }


    /**

     * Retrieves a property descriptor object for a given property.

     * <p>

     * Uses the classes in <code>java.beans</code> to get back

     * a descriptor for a property.  Read-only and write-only

     * properties will have a slower return time.

     * </p>

     *

     * @param propertyName The programmatic name of the property

     * @param beanClass The Class object for the target bean.

     *                  For example sun.beans.OurButton.class.

     * @return a PropertyDescriptor for a property that follows the

     *         standard Java naming conventions.

     * @throws PropertyNotFoundException indicates that the property

     *         could not be found on the bean class.

     */

    private static final PropertyDescriptor getPropertyDescriptor(

            String propertyName, Class beanClass) {


        PropertyDescriptor resultPropertyDescriptor = null;


        char[] pNameArray = propertyName.toCharArray();

        pNameArray[0] = Character.toLowerCase(pNameArray[0]);

        propertyName = new String(pNameArray);


        try {

            resultPropertyDescriptor = new PropertyDescriptor(propertyName,

                    beanClass);

        } catch (IntrospectionException e1) {

            // Read-only and write-only properties will throw this

            // exception.  The properties must be looked up using

            // brute force.


            // This will get the list of all properties and iterate

            // through looking for one that matches the property

            // name passed into the method.

            try {

                BeanInfo beanInfo = 
展开阅读全文