Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
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.
/*
* 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));
}
}