001/*
002 *    Copyright 2024-2025, Warm-Flow (290631660@qq.com).
003 *
004 *    Licensed under the Apache License, Version 2.0 (the "License");
005 *    you may not use this file except in compliance with the License.
006 *    You may obtain a copy of the License at
007 *
008 *       https://www.apache.org/licenses/LICENSE-2.0
009 *
010 *    Unless required by applicable law or agreed to in writing, software
011 *    distributed under the License is distributed on an "AS IS" BASIS,
012 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *    See the License for the specific language governing permissions and
014 *    limitations under the License.
015 */
016package org.dromara.warm.flow.core.utils;
017
018import java.lang.reflect.Constructor;
019import java.lang.reflect.Field;
020import java.lang.reflect.Modifier;
021import java.util.Objects;
022
023/**
024 * 类工具类
025 *
026 * @author warm
027 */
028public class ClassUtil {
029    /**
030     * 通过包名获取Class对象
031     */
032    public static Class<?> getClazz(String className) {
033        try {
034            return Class.forName(className);
035        } catch (ClassNotFoundException e) {
036            return null;
037        }
038    }
039
040    /**
041     * 通过反射实现对象克隆
042     *
043     * @param origin
044     * @param <C>
045     * @return
046     */
047    public static <C> C clone(C origin) {
048        if (Objects.isNull(origin)) {
049            return null;
050        }
051        try {
052            // 获取对象的类信息
053            Class<C> clazz = (Class<C>) origin.getClass();
054            // 创建新的对象实例
055            Constructor<C> constructors = clazz.getConstructor();
056            // 创建一个对象
057            C instance = constructors.newInstance();
058            // 获取对象的所有字段
059            Field[] fields = clazz.getDeclaredFields();
060            // 遍历字段进行赋值
061            for (Field field : fields) {
062                // 设置可访问性
063                makeAccessible(field);
064                // 跳过静态字段和常量字段
065                int modifiers = field.getModifiers();
066                if (Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers)) {
067                    continue;
068                }
069                // 获取字段的值,并设置到克隆对象中
070                Object value = field.get(origin);
071                field.set(instance, value);
072            }
073
074            return instance;
075        } catch (Exception e) {
076            return null;
077        }
078    }
079
080    /**
081     * 让指定字段变为可访问
082     *
083     * @param field
084     */
085    public static void makeAccessible(Field field) {
086        if ((!Modifier.isPublic(field.getModifiers())
087                || !Modifier.isPublic(field.getDeclaringClass().getModifiers())
088                || Modifier.isFinal(field.getModifiers()))
089                && !field.isAccessible()) {
090            field.setAccessible(true);
091        }
092    }
093}