com.github.yulichang.toolkit.ReflectionKit Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mybatis-plus-join-core Show documentation
Show all versions of mybatis-plus-join-core Show documentation
An enhanced toolkit of Mybatis-Plus to simplify development.
/*
* Copyright (c) 2011-2022, baomidou ([email protected]).
*
* 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.github.yulichang.toolkit;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.github.yulichang.toolkit.reflect.GenericTypeUtils;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;
/**
* 反射工具类,提供反射相关的快捷操作
*
* @author Caratacus
* @author hcl
* @since 2016-09-22
*/
@SuppressWarnings("All")
public final class ReflectionKit {
/**
* class field cache
*/
private static final Map, List> CLASS_FIELD_CACHE = new ConcurrentHashMap<>();
@Deprecated
private static final Map, Class>> PRIMITIVE_WRAPPER_TYPE_MAP = new IdentityHashMap<>(8);
private static final Map, Class>> PRIMITIVE_TYPE_TO_WRAPPER_MAP = new IdentityHashMap<>(8);
static {
PRIMITIVE_WRAPPER_TYPE_MAP.put(Boolean.class, boolean.class);
PRIMITIVE_WRAPPER_TYPE_MAP.put(Byte.class, byte.class);
PRIMITIVE_WRAPPER_TYPE_MAP.put(Character.class, char.class);
PRIMITIVE_WRAPPER_TYPE_MAP.put(Double.class, double.class);
PRIMITIVE_WRAPPER_TYPE_MAP.put(Float.class, float.class);
PRIMITIVE_WRAPPER_TYPE_MAP.put(Integer.class, int.class);
PRIMITIVE_WRAPPER_TYPE_MAP.put(Long.class, long.class);
PRIMITIVE_WRAPPER_TYPE_MAP.put(Short.class, short.class);
for (Map.Entry, Class>> entry : PRIMITIVE_WRAPPER_TYPE_MAP.entrySet()) {
PRIMITIVE_TYPE_TO_WRAPPER_MAP.put(entry.getValue(), entry.getKey());
}
}
/**
* 获取字段值
*
* @param entity 实体
* @param fieldName 字段名称
* @return 属性值
*/
public static Object getFieldValue(Object entity, String fieldName) {
Class> cls = entity.getClass();
Map fieldMaps = getFieldMap(cls);
try {
Field field = fieldMaps.get(fieldName);
Assert.notNull(field, "Error: NoSuchField in %s for %s. Cause:", cls.getSimpleName(), fieldName);
field.setAccessible(true);
return field.get(entity);
} catch (ReflectiveOperationException e) {
throw ExceptionUtils.mpe("Error: Cannot read field in %s. Cause:", e, cls.getSimpleName());
}
}
/**
*
* 反射对象获取泛型
*
*
* @param clazz 对象
* @param genericIfc 所属泛型父类
* @param index 泛型所在位置
* @return Class
*/
public static Class> getSuperClassGenericType(final Class> clazz, final Class> genericIfc, final int index) {
//update by noear @2021-09-03
Class>[] typeArguments = GenericTypeUtils.resolveTypeArguments(ClassUtils.getUserClass(clazz), genericIfc);
return null == typeArguments ? null : typeArguments[index];
}
/**
*
* 获取该类的所有属性列表
*
*
* @param clazz 反射类
*/
public static Map getFieldMap(Class> clazz) {
List fieldList = getFieldList(clazz);
return CollectionUtils.isNotEmpty(fieldList) ? fieldList.stream().collect(Collectors.toMap(Field::getName, Function.identity())) : Collections.emptyMap();
}
/**
*
* 获取该类的所有属性列表
*
*
* @param clazz 反射类
*/
public static List getFieldList(Class> clazz) {
if (Objects.isNull(clazz)) {
return Collections.emptyList();
}
return computeIfAbsent(CLASS_FIELD_CACHE, clazz, k -> {
Field[] fields = k.getDeclaredFields();
List superFields = new ArrayList<>();
Class> currentClass = k.getSuperclass();
while (currentClass != null) {
Field[] declaredFields = currentClass.getDeclaredFields();
Collections.addAll(superFields, declaredFields);
currentClass = currentClass.getSuperclass();
}
/* 排除重载属性 */
Map fieldMap = excludeOverrideSuperField(fields, superFields);
/*
* 重写父类属性过滤后处理忽略部分,支持过滤父类属性功能
* 场景:中间表不需要记录创建时间,忽略父类 createTime 公共属性
* 中间表实体重写父类属性 ` private transient Date createTime; `
*/
return fieldMap.values().stream()
/* 过滤静态属性 */
.filter(f -> !Modifier.isStatic(f.getModifiers()))
/* 过滤 transient关键字修饰的属性 */
.filter(f -> !Modifier.isTransient(f.getModifiers()))
.collect(Collectors.toList());
});
}
/**
*
* 排序重置父类属性
*
*
* @param fields 子类属性
* @param superFieldList 父类属性
*/
public static Map excludeOverrideSuperField(Field[] fields, List superFieldList) {
// 子类属性
Map fieldMap = Stream.of(fields).collect(toMap(Field::getName, identity(),
(u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
},
LinkedHashMap::new));
superFieldList.stream().filter(field -> !fieldMap.containsKey(field.getName()))
.forEach(f -> fieldMap.put(f.getName(), f));
return fieldMap;
}
/**
* 判断是否为基本类型或基本包装类型
*
* @param clazz class
* @return 是否基本类型或基本包装类型
*/
@Deprecated
public static boolean isPrimitiveOrWrapper(Class> clazz) {
Assert.notNull(clazz, "Class must not be null");
return (clazz.isPrimitive() || PRIMITIVE_WRAPPER_TYPE_MAP.containsKey(clazz));
}
public static Class> resolvePrimitiveIfNecessary(Class> clazz) {
return (clazz.isPrimitive() && clazz != void.class ? PRIMITIVE_TYPE_TO_WRAPPER_MAP.get(clazz) : clazz);
}
/**
* 设置可访问对象的可访问权限为 true
*
* @param object 可访问的对象
* @param 类型
* @return 返回设置后的对象
*/
public static T setAccessible(T object) {
return AccessController.doPrivileged(new SetAccessibleAction<>(object));
}
public static V computeIfAbsent(Map concurrentHashMap, K key, Function super K, ? extends V> mappingFunction) {
V v = concurrentHashMap.get(key);
if (v != null) {
return v;
}
return concurrentHashMap.computeIfAbsent(key, mappingFunction);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy