Java tutorial
/* * Copyright (C) 2008 feilong * * 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.core.lang.reflect; import static org.apache.commons.lang3.StringUtils.EMPTY; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.apache.commons.collections4.Predicate; import org.apache.commons.collections4.PredicateUtils; import org.apache.commons.lang3.reflect.FieldUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.feilong.core.util.CollectionsUtil; import com.feilong.core.util.predicate.BeanPredicateUtil; import com.feilong.tools.slf4j.Slf4jUtil; import static com.feilong.core.Validator.isNullOrEmpty; /** * focus on {@link Field} ?? * * <p> * 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. * </p> * * <h3> {@link Field} :</h3> * * <blockquote> * <table border="1" cellspacing="0" cellpadding="4" summary=""> * <tr style="background-color:#ccccff"> * <th align="left"></th> * <th align="left"></th> * </tr> * <tr valign="top"> * <td>{@link Class#getDeclaredFields() getDeclaredFields}</td> * <td> {@link Field} ,?? Class ?<span style="color:green"></span>. * * <p> * <span style="color:green"><b></b>?<b>?</b>?<b>()</b><b>?</b></span>, <span style="color:red">?</span>. * </p> * * <b>?,?.</b><br> * ??, Class ? void, 0 .</td> * </tr> * * <tr valign="top" style="background-color:#eeeeff"> * <td>{@link Class#getFields() getFields}</td> * <td>?? {@link Field} ,?? Class ? <span style="color:red">?</span>. * * <p> * , Class <b></b>,<span style="color:red">?</span>.<br> * Class <b>?</b>,<span style="color:red">???</span>. * </p> * * <p> * ?,?. * </p> * <br> * * ??,? void, 0 . <br> * ?????.? {@link java.lang.reflect.Array} ??.</td> * </tr> * * <tr valign="top"> * <td>{@link Class#getDeclaredField(String) getDeclaredField}</td> * <td> {@link Field} ,?? Class ?.<br> * ?,??? length .</td> * </tr> * * <tr valign="top" style="background-color:#eeeeff"> * <td>{@link Class#getField(String) getField}</td> * <td> {@link Field} ,?? Class ?<span style="color:green">?</span>.<br> * ????.<br> * C : <br> * C ??,???. <br> * 1 , C ?<b>?</b>.???. <br> * 1?2 , C <b> S</b>, S . C , NoSuchFieldException.<br> * </td> * </tr> * </table> * </blockquote> * * @author <a href="http://feitianbenyue.iteye.com/">feilong</a> * @see org.apache.commons.lang3.reflect.FieldUtils * @see "org.springframework.util.ReflectionUtils" * @since 1.0.7 */ public final class FieldUtil { /** The Constant LOGGER. */ private static final Logger LOGGER = 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!"); } /** * <code>obj</code> (<b>?</b>),key fieldName,value . * * <h3>:</h3> * * <blockquote> * * <pre class="code"> * * User user = new User(12L); * LOGGER.debug(JsonUtil.format(FieldUtil.getAllFieldNameAndValueMap(user, "date"))); * * </pre> * * <b>:</b> * * <pre class="code"> * { * "age": null, * "id": 12 * } * * </pre> * * </blockquote> * * @param obj * the obj * @param excludeFieldNames * ?field names,?nullOrEmpty ? * @return <code>obj</code> null, {@link NullPointerException}<br> * <code>fieldList</code> nullempty, {@link Collections#emptyMap()}<br> * @see #getAllFieldList(Class, String...) * @see #getFieldValue(Object, String) */ public static Map<String, Object> getAllFieldNameAndValueMap(Object obj, String... excludeFieldNames) { List<Field> fieldList = getAllFieldList(obj.getClass(), excludeFieldNames); if (isNullOrEmpty(fieldList)) { return Collections.emptyMap(); } Map<String, Object> map = new TreeMap<String, Object>(); for (Field field : fieldList) { map.put(field.getName(), getFieldValue(obj, field.getName())); } return map; } /** * <code>klass</code> ? <code>excludeFieldNames</code> ?list. * * @param klass * the klass * @param excludeFieldNames * ?field names,?nullOrEmpty ? * @return <code>obj</code> null, {@link NullPointerException}<br> * {@link FieldUtils#getAllFieldsList(Class)} nullempty, {@link Collections#emptyList()}<br> * @see FieldUtils#getAllFieldsList(Class) * @since 1.7.1 */ //no static public static List<Field> getAllFieldList(final Class<?> klass, String... excludeFieldNames) { // {@link Field},parents, public/protect/private/inherited... List<Field> fieldList = FieldUtils.getAllFieldsList(klass); if (isNullOrEmpty(fieldList)) { return Collections.emptyList(); } //********************************************************************************************** Predicate<Field> excludeFieldPredicate = BeanPredicateUtil.containsPredicate("name", excludeFieldNames); Predicate<Field> staticPredicate = new Predicate<Field>() { @Override public boolean evaluate(Field field) { int modifiers = field.getModifiers(); // ??? log serialVersionUID boolean isStatic = Modifier.isStatic(modifiers); String pattern = "[{}.{}],modifiers:[{}]{}"; LOGGER.trace(pattern, klass.getSimpleName(), field.getName(), modifiers, isStatic ? " [isStatic]" : EMPTY); return isStatic; } }; return CollectionsUtil.selectRejected(fieldList, PredicateUtils.orPredicate(excludeFieldPredicate, staticPredicate)); } /** * ? <code>owner</code> <code>fieldName</code> . * * @param <T> * the generic type * @param obj * the owner * @param fieldName * the field name * @return <code>owner</code> null, {@link NullPointerException}<br> * <code>fieldName</code> null, {@link NullPointerException}<br> * <code>fieldName</code> blank, {@link IllegalArgumentException}<br> * @see org.apache.commons.lang3.reflect.FieldUtils#readField(Object, String, boolean) * @since 1.4.0 */ @SuppressWarnings("unchecked") public static <T> T getFieldValue(Object obj, String fieldName) { try { return (T) FieldUtils.readField(obj, fieldName, true); } catch (IllegalAccessException e) { String message = Slf4jUtil.format("ownerClass:[{}],fieldName:[{}],ownerObj:[{}]", obj.getClass().getName(), fieldName, obj); LOGGER.error(message, e); throw new ReflectException(message, e); } } }