com.feilong.commons.core.lang.reflect.FieldUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.feilong.commons.core.lang.reflect.FieldUtil.java

Source

/*
 * Copyright (C) 2008 feilong (venusdrogon@163.com)
 *
 * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.feilong.commons.core.lang.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.feilong.commons.core.lang.ClassUtil;
import com.feilong.commons.core.util.ArrayUtil;
import com.feilong.commons.core.util.Validator;

/**
 * Utilities for working with Fields by reflection. <br>
 * Adapted and refactored from the dormant [reflect] Commons sandbox component.
 * 
 * The ability is provided to break the scoping restrictions coded by the programmer.<br>
 * This can allow fields to be changed that shouldn't be.
 * This facility should be used with care.
 * 
 * @author <a href="mailto:venusdrogon@163.com">feilong</a>
 * @version 1.0.7 2014715 ?1:08:15
 * @see org.apache.commons.lang3.reflect.FieldUtils
 * @see "org.springframework.util.ReflectionUtils"
 * @since 1.0.7
 */
//TODO ?
public final class FieldUtil {

    /** The Constant log. */
    private static final Logger log = LoggerFactory.getLogger(FieldUtil.class);

    /** Don't let anyone instantiate this class. */
    private FieldUtil() {
        //AssertionError?. ?????. ???.
        //see Effective Java 2nd
        throw new AssertionError("No " + getClass().getName() + " instances for you!");
    }

    // [start] Field

    /**
     *  (?),key fieldNamevalue .
     * 
     * @param obj
     *            the obj
     * @return the field value map,key fieldNamevalue 
     * @throws ReflectException
     *             the reflect exception
     * @see #getDeclaredFields(Object)
     * @see #getFieldValueMap(Object, String[])
     * @see java.lang.reflect.Modifier#isPrivate(int)
     * @see java.lang.reflect.Modifier#isStatic(int)
     */
    public static Map<String, Object> getFieldValueMap(Object obj) throws ReflectException {
        return getFieldValueMap(obj, null);
    }

    /**
     *  (?),key fieldNamevalue .
     *
     * @param obj
     *            the obj
     * @param excludeFieldNames
     *            ?field names,?nullOrEmpty ?
     * @return the field value map
     * @throws ReflectException
     *             the reflect exception
     */
    public static Map<String, Object> getFieldValueMap(Object obj, String[] excludeFieldNames)
            throws ReflectException {

        // (?,)
        Field[] fields = getDeclaredFields(obj);

        Map<String, Object> map = new TreeMap<String, Object>();
        if (Validator.isNotNullOrEmpty(fields)) {
            for (Field field : fields) {
                String fieldName = field.getName();

                if (Validator.isNotNullOrEmpty(excludeFieldNames)
                        && ArrayUtil.isContain(excludeFieldNames, fieldName)) {
                    continue;
                }

                int modifiers = field.getModifiers();
                // ??? log
                boolean isPrivateAndStatic = Modifier.isPrivate(modifiers) && Modifier.isStatic(modifiers);
                log.debug("field name:[{}],modifiers:[{}],isPrivateAndStatic:[{}]", fieldName, modifiers,
                        isPrivateAndStatic);

                if (!isPrivateAndStatic) {
                    //TODO see org.apache.commons.lang3.reflect.MemberUtils.setAccessibleWorkaround(AccessibleObject)
                    field.setAccessible(true);
                    try {
                        map.put(fieldName, field.get(obj));
                    } catch (Exception e) {
                        log.error(e.getClass().getName(), e);
                        throw new ReflectException(e);
                    }
                }
            }
        }
        return map;
    }

    /**
     *  {@link java.lang.reflect.Field}(? private, inherited ).
     * 
     * @param obj
     *            the obj
     * @return the declared fields
     * @see java.lang.Class#getDeclaredFields()
     * @see java.lang.Class#getSuperclass()
     * @see java.lang.reflect.Field
     * @see org.apache.commons.lang3.ArrayUtils#addAll(boolean[], boolean...)
     */
    private static Field[] getDeclaredFields(Object obj) {
        Class<?> klass = obj.getClass();
        Class<?> superClass = klass.getSuperclass();

        //Class????(??public)
        Field[] fields = klass.getDeclaredFields();
        do {
            if (log.isDebugEnabled()) {
                log.debug("current class:[{}],super class:[{}]", klass.getName(), superClass.getName());
            }
            fields = ArrayUtils.addAll(fields, superClass.getDeclaredFields());
            superClass = superClass.getSuperclass();

        } while (null != superClass && superClass != Object.class);

        return fields;
    }

    /**
     *  Field ?? Class?,..
     * 
     * <pre>
     * public,protected,,private
     * ?.
     * 
     * ??.
     * ?? Class ? void 0 .
     * </pre>
     * 
     * @param clz
     *            the clz
     * @return public,protected,,private?.
     * @see java.lang.Class#getDeclaredFields()
     * @see #getFieldsNames(Field[])
     */
    public static String[] getDeclaredFieldNames(Class<?> clz) {
        Field[] declaredFields = clz.getDeclaredFields();
        return getFieldsNames(declaredFields);
    }

    /**
     * ?? Class ??(public)<br>
     * ??<br>
     * ??? void 0 . <br>
     *  Class ?.<br>
     *  Class ????. <br>
     * .
     * 
     * @param clz
     *            the clz
     * @return the field names
     * @see Class#getFields()
     * @see #getFieldsNames(Field[])
     */
    public static String[] getFieldNames(Class<?> clz) {
        Field[] fields = clz.getFields();
        return getFieldsNames(fields);
    }

    /**
     * Field[] fields,?field name ?.
     * 
     * @param fields
     *            the fields
     * @return  fields isNullOrEmpty, null;??field name,?
     * @see java.lang.reflect.Field#getName()
     */
    private static String[] getFieldsNames(Field[] fields) {
        if (Validator.isNullOrEmpty(fields)) {
            return null;
        }
        String[] fieldNames = new String[fields.length];
        for (int j = 0; j < fields.length; ++j) {
            fieldNames[j] = fields[j].getName();
        }
        return fieldNames;
    }

    /**
     *  Field ?? Class ?.
     * 
     * @param clz
     *            clz
     * @param name
     *            ??
     * @return  Field ?? Class ?
     * @throws ReflectException
     *             the reflect exception
     * @see java.lang.Class#getDeclaredField(String)
     */
    public static Field getDeclaredField(Class<?> clz, String name) throws ReflectException {
        try {
            Field field = clz.getDeclaredField(name);
            return field;
        } catch (Exception e) {
            log.error(e.getClass().getName(), e);
            throw new ReflectException(e);
        }
    }

    // [end]

    // [start] Property

    /**
     * .
     * 
     * @param owner
     *            the owner
     * @param fieldName
     *            
     * @param value
     *            
     * @throws ReflectException
     *             the reflect exception
     * @see java.lang.Object#getClass()
     * @see java.lang.Class#getField(String)
     * @see java.lang.reflect.Field#set(Object, Object)
     */
    public static void setProperty(Object owner, String fieldName, Object value) throws ReflectException {
        try {
            Class<?> ownerClass = owner.getClass();
            Field field = ownerClass.getField(fieldName);
            field.set(ownerClass, value);
        } catch (Exception e) {
            log.error(e.getClass().getName(), e);
            throw new ReflectException(e);
        }
    }

    /**
     * ?.
     * 
     * @param <T>
     *            the generic type
     * @param owner
     *            the owner
     * @param fieldName
     *            the field name
     * @return 
     * @throws ReflectException
     *             the reflect exception
     * 
     * @see java.lang.Object#getClass()
     * @see java.lang.Class#getField(String)
     * @see java.lang.reflect.Field#get(Object)
     */
    @SuppressWarnings("unchecked")
    public static <T> T getProperty(Object owner, String fieldName) throws ReflectException {
        try {
            Class<?> ownerClass = owner.getClass();
            Field field = ownerClass.getField(fieldName);
            Object property = field.get(owner);
            return (T) property;
        } catch (Exception e) {
            log.error(e.getClass().getName(), e);
            throw new ReflectException(e);
        }
    }

    /**
     * ???.
     * 
     * <pre>
     * {@code
     * example1 :
     *  IOConstants GB??
     * FieldUtil.getStaticProperty("com.feilong.commons.core.io.IOConstants", "GB")
     *  :1073741824
     * }
     * </pre>
     * 
     * @param <T>
     *            the generic type
     * @param className
     *            ??
     * @param fieldName
     *            ??
     * @return 
     * @throws ReflectException
     *             the reflect exception
     * @see com.feilong.commons.core.lang.ClassUtil#loadClass(String)
     * @see java.lang.Class#getField(String)
     * @see java.lang.reflect.Field#get(Object)
     */
    @SuppressWarnings("unchecked")
    public static <T> T getStaticProperty(String className, String fieldName) throws ReflectException {
        try {
            Class<?> ownerClass = ClassUtil.loadClass(className);
            Field field = ownerClass.getField(fieldName);
            Object property = field.get(ownerClass);
            return (T) property;
        } catch (Exception e) {
            log.error(e.getClass().getName(), e);
            throw new ReflectException(e);
        }
    }

    // [end]
}