All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.guerlab.commons.reflection.FieldUtil Maven / Gradle / Ivy

Go to download

net.guerlab.commons is a suite of core and expanded libraries that include utility classes and much much more.

The newest version!
/*
 * Copyright 2018-2021 guerlab.net and other contributors.
 *
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.guerlab.commons.reflection;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 类字段工具
 *
 * @author guer
 */
public final class FieldUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(FieldUtil.class);

    private static final Class[] BASE_NUMBER_CLASS_LIST = new Class[] { Byte.TYPE, Short.TYPE, Integer.TYPE,
            Long.TYPE, Float.TYPE, Double.TYPE };

    private static SoftReference, List>> CACHE = new SoftReference<>(new ConcurrentHashMap<>());

    private FieldUtil() {
    }

    /**
     * 获取缓存
     *
     * @return 缓存
     */
    private static Map, List> getCache() {
        Map, List> caches = CACHE.get();
        if (caches == null) {
            CACHE = new SoftReference<>(caches = new ConcurrentHashMap<>(8));
        }

        return caches;
    }

    /**
     * 读取属性值
     *
     * @param object
     *         对象
     * @param field
     *         字段
     * @return 属性值
     */
    public static Object get(Object object, Field field) {
        try {
            return read(object, field);
        } catch (Exception e) {
            LOGGER.trace(e.getMessage(), e);
        }
        return null;
    }

    /**
     * 读取属性值
     *
     * @param object
     *         对象
     * @param name
     *         属性名
     * @return 属性值
     */
    public static Object get(Object object, String name) {
        return get(object, getField(object.getClass(), name));
    }

    /**
     * 读取属性值
     *
     * @param object
     *         对象
     * @param name
     *         属性名
     * @return 属性值
     * @throws IllegalAccessException
     *         if this {@code Method} object
     *         is enforcing Java language access control and the underlying
     *         method is inaccessible.
     * @throws InvocationTargetException
     *         if the underlying method
     *         throws an exception.
     * @throws IntrospectionException
     *         if an exception occurs during introspection.
     */
    public static Object read(Object object, String name)
            throws IllegalAccessException, InvocationTargetException, IntrospectionException {
        return read(object, getField(object.getClass(), name));
    }

    /**
     * 读取属性值
     *
     * @param object
     *         对象
     * @param field
     *         字段
     * @return 属性值
     * @throws IllegalAccessException
     *         if this {@code Method} object
     *         is enforcing Java language access control and the underlying
     *         method is inaccessible.
     * @throws InvocationTargetException
     *         if the underlying method
     *         throws an exception.
     * @throws IntrospectionException
     *         if an exception occurs during introspection.
     */
    public static Object read(Object object, Field field)
            throws IllegalAccessException, InvocationTargetException, IntrospectionException {
        if (field == null) {
            return null;
        } else if (Modifier.isPublic(field.getModifiers())) {
            return field.get(object);
        }

        PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), object.getClass());
        Method method = propertyDescriptor.getReadMethod();
        return method.invoke(object);
    }

    /**
     * 设置属性
     *
     * @param object
     *         对象
     * @param field
     *         字段
     * @param value
     *         属性值
     */
    public static void put(Object object, Field field, Object value) {
        try {
            write(object, field, value);
        } catch (Exception e) {
            LOGGER.trace(e.getMessage(), e);
        }
    }

    /**
     * 设置属性
     *
     * @param object
     *         对象
     * @param name
     *         属性名
     * @param value
     *         属性值
     */
    public static void put(Object object, String name, Object value) {
        put(object, getField(object.getClass(), name), value);
    }

    /**
     * 设置属性
     *
     * @param object
     *         对象
     * @param name
     *         属性名
     * @param value
     *         属性值
     * @throws IntrospectionException
     *         if an exception occurs during
     *         introspection.
     * @throws InvocationTargetException
     *         if the underlying method
     *         throws an exception.
     * @throws IllegalAccessException
     *         if this {@code Method} object
     *         is enforcing Java language access control and the underlying
     *         method is inaccessible.
     */
    public static void write(Object object, String name, Object value)
            throws IntrospectionException, InvocationTargetException, IllegalAccessException {
        write(object, getField(object.getClass(), name), value);
    }

    /**
     * 设置属性
     *
     * @param object
     *         对象
     * @param field
     *         字段
     * @param value
     *         属性值
     * @throws IntrospectionException
     *         if an exception occurs during
     *         introspection.
     * @throws InvocationTargetException
     *         if the underlying method
     *         throws an exception.
     * @throws IllegalAccessException
     *         if this {@code Method} object
     *         is enforcing Java language access control and the underlying
     *         method is inaccessible.
     */
    public static void write(Object object, Field field, Object value)
            throws IntrospectionException, InvocationTargetException, IllegalAccessException {
        if (field == null) {
            return;
        } else if (Modifier.isPublic(field.getModifiers())) {
            field.set(object, value);
            return;
        }

        PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), object.getClass());
        Method method = propertyDescriptor.getWriteMethod();
        method.invoke(object, value);
    }

    /**
     * 判断某个类型是否为数值类
     *
     * @param fieldType
     *         字段类型
     * @return 是否为数值类型
     */
    public static boolean isNumberClass(Class fieldType) {
        if (fieldType == null) {
            return false;
        }

        if (Number.class.isAssignableFrom(fieldType)) {
            return true;
        }

        return Arrays.stream(BASE_NUMBER_CLASS_LIST).anyMatch(element -> element == fieldType);
    }

    /**
     * 根据类对象获取字段列表
     *
     * @param clazz
     *         类对象
     * @return 字段列表
     */
    public static List getFields(Class clazz) {
        if (clazz == null) {
            return Collections.emptyList();
        }

        Map, List> cache = getCache();
        List allFields = cache.get(clazz);

        if (allFields != null) {
            return allFields;
        }

        allFields = new ArrayList<>();
        Deque> classes = new LinkedList<>();
        Class paramsClass = clazz;

        while (true) {
            Class superClass = paramsClass.getSuperclass();
            classes.add(paramsClass);

            if (Object.class.equals(superClass)) {
                break;
            }

            paramsClass = paramsClass.getSuperclass();
        }

        while (!classes.isEmpty()) {
            allFields.addAll(Arrays.asList(classes.pollFirst().getDeclaredFields()));
        }

        cache.put(clazz, allFields);

        return allFields;
    }

    /**
     * 根据类对象获取字段列表
     *
     * @param clazz
     *         类对象
     * @return 字段列表
     */
    public static Field getField(Class clazz, String name) {
        return getFields(clazz).stream().filter(field -> Objects.equals(field.getName(), name)).findFirst()
                .orElse(null);
    }

    /**
     * 获取过滤后的字段列表
     *
     * @param clazz
     *         类对象
     * @param filters
     *         过滤器列表
     * @return 字段列表
     */
    public static List getFieldsWithFilter(Class clazz, Collection> filters) {
        List list = getFields(clazz);

        if (list.isEmpty()) {
            return Collections.emptyList();
        }

        Stream stream = list.stream().filter(Objects::nonNull);

        if (filters != null && !filters.isEmpty()) {
            for (Predicate filter : filters) {
                if (filter != null) {
                    stream = stream.filter(filter);
                }
            }
        }

        return stream.collect(Collectors.toList());
    }

    /**
     * 获取过滤后的字段列表
     *
     * @param clazz
     *         类对象
     * @param filters
     *         过滤器列表
     * @return 字段列表
     */
    @SafeVarargs
    public static List getFieldsWithFilter(Class clazz, Predicate... filters) {
        return getFieldsWithFilter(clazz, Arrays.asList(filters));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy