Java tutorial
/* * 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] }