From b6f970ce20c3dc6eeacd4fb89323c51fb5cf57ce Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 4 May 2023 00:51:31 +0800 Subject: [PATCH] fix code --- hutool-core/pom.xml | 16 +++ .../core/classloader/ClassLoaderUtil.java | 18 +--- .../org/dromara/hutool/core/lang/Opt.java | 2 +- .../hutool/core/reflect/kotlin/KCallable.java | 49 ++++++++++ .../core/reflect/kotlin/KClassImpl.java | 46 +++++++++ .../core/reflect/kotlin/KClassUtil.java | 51 ++++++++++ .../core/reflect/kotlin/KParameter.java | 98 +++++++++++++++++++ .../core/reflect/kotlin/package-info.java | 22 +++++ .../core/reflect/kotlin/KClassUtilTest.java | 42 ++++++++ .../hutool/core/reflect/kotlin/TestKBean.kt | 15 +++ 10 files changed, 342 insertions(+), 17 deletions(-) create mode 100644 hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KCallable.java create mode 100644 hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KClassImpl.java create mode 100644 hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KClassUtil.java create mode 100644 hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KParameter.java create mode 100644 hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/package-info.java create mode 100644 hutool-core/src/test/java/org/dromara/hutool/core/reflect/kotlin/KClassUtilTest.java create mode 100644 hutool-core/src/test/java/org/dromara/hutool/core/reflect/kotlin/TestKBean.kt diff --git a/hutool-core/pom.xml b/hutool-core/pom.xml index 4b93fd533..4926e742b 100755 --- a/hutool-core/pom.xml +++ b/hutool-core/pom.xml @@ -30,6 +30,22 @@ org.dromara.hutool.core + 1.8.21 + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin-version} + test + + + org.jetbrains.kotlin + kotlin-reflect + ${kotlin-version} + test + + + diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/classloader/ClassLoaderUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/classloader/ClassLoaderUtil.java index 1f3b86824..c4ca28513 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/classloader/ClassLoaderUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/classloader/ClassLoaderUtil.java @@ -16,8 +16,6 @@ import org.dromara.hutool.core.exception.HutoolException; import org.dromara.hutool.core.reflect.ClassDescUtil; import java.io.File; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * {@link ClassLoader}工具类
@@ -58,13 +56,7 @@ public class ClassLoaderUtil { * @see Thread#getContextClassLoader() */ public static ClassLoader getContextClassLoader() { - if (System.getSecurityManager() == null) { - return Thread.currentThread().getContextClassLoader(); - } else { - // 绕开权限检查 - return AccessController.doPrivileged( - (PrivilegedAction) () -> Thread.currentThread().getContextClassLoader()); - } + return Thread.currentThread().getContextClassLoader(); } /** @@ -75,13 +67,7 @@ public class ClassLoaderUtil { * @since 5.7.0 */ public static ClassLoader getSystemClassLoader() { - if (System.getSecurityManager() == null) { - return ClassLoader.getSystemClassLoader(); - } else { - // 绕开权限检查 - return AccessController.doPrivileged( - (PrivilegedAction) ClassLoader::getSystemClassLoader); - } + return ClassLoader.getSystemClassLoader(); } /** diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/Opt.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/Opt.java index 9d68a8ae3..7c07a98fa 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/lang/Opt.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/Opt.java @@ -72,7 +72,7 @@ public class Opt { */ public static Opt ofNullable(final T value) { return value == null ? empty() - : new Opt<>(value); + : new Opt<>(value); } /** diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KCallable.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KCallable.java new file mode 100644 index 000000000..2896e500b --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KCallable.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.core.reflect.kotlin; + +import org.dromara.hutool.core.classloader.ClassLoaderUtil; +import org.dromara.hutool.core.reflect.MethodUtil; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +/** + * kotlin.reflect.KCallable方法包装调用类 + * + * @author VampireAchao, Looly + */ +public class KCallable { + private static final Method METHOD_GET_PARAMETERS; + + static { + final Class kFunctionClass = ClassLoaderUtil.loadClass("kotlin.reflect.KCallable"); + METHOD_GET_PARAMETERS = MethodUtil.getMethod(kFunctionClass, "getParameters"); + } + + /** + * 获取参数列表 + * + * @param kCallable kotlin的类、方法或构造 + * @return 参数列表 + */ + public static List getParameters(final Object kCallable) { + final List parameters = MethodUtil.invoke(kCallable, METHOD_GET_PARAMETERS); + final List result = new ArrayList<>(parameters.size()); + for (final Object parameter : parameters) { + result.add(new KParameter(parameter)); + } + return result; + } +} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KClassImpl.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KClassImpl.java new file mode 100644 index 000000000..5e56273d6 --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KClassImpl.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.core.reflect.kotlin; + +import org.dromara.hutool.core.classloader.ClassLoaderUtil; +import org.dromara.hutool.core.reflect.ConstructorUtil; +import org.dromara.hutool.core.reflect.MethodUtil; + +import java.lang.reflect.Method; +import java.util.List; + +/** + * kotlin.reflect.jvm.internal.KClassImpl包装 + * + * @author VampireAchao, Looly + */ +public class KClassImpl { + private static final Class KCLASS_IMPL_CLASS; + private static final Method METHOD_GET_CONSTRUCTORS; + + static { + KCLASS_IMPL_CLASS = ClassLoaderUtil.loadClass("kotlin.reflect.jvm.internal.KClassImpl"); + METHOD_GET_CONSTRUCTORS = MethodUtil.getMethod(KCLASS_IMPL_CLASS, "getConstructors"); + } + + /** + * 获取Kotlin类的所有构造方法 + * + * @param targetType kotlin类 + * @return 构造列表 + */ + public static List getConstructors(final Class targetType) { + final Object kClassImpl = ConstructorUtil.newInstance(KCLASS_IMPL_CLASS, targetType); + return MethodUtil.invoke(kClassImpl, METHOD_GET_CONSTRUCTORS); + } +} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KClassUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KClassUtil.java new file mode 100644 index 000000000..d1ca297c4 --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KClassUtil.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.core.reflect.kotlin; + +import org.dromara.hutool.core.lang.Opt; + +import java.util.List; + +/** + * Kotlin反射包装相关工具类 + * + * @author VampireAchao, Looly + */ +public class KClassUtil { + + /** + * 是否提供或处于Kotlin环境中 + */ + public static final boolean IS_KOTLIN_ENABLE = + Opt.ofTry(() -> Class.forName("kotlin.Metadata")).isPresent(); + + /** + * 获取Kotlin类的所有构造方法 + * + * @param targetType kotlin类 + * @return 构造列表 + */ + public static List getConstructors(final Class targetType) { + return KClassImpl.getConstructors(targetType); + } + + /** + * 获取参数列表 + * + * @param kCallable kotlin的类、方法或构造 + * @return 参数列表 + */ + public static List getParameters(final Object kCallable) { + return KCallable.getParameters(kCallable); + } +} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KParameter.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KParameter.java new file mode 100644 index 000000000..f20643a2b --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/KParameter.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.core.reflect.kotlin; + +import org.dromara.hutool.core.classloader.ClassLoaderUtil; +import org.dromara.hutool.core.reflect.MethodUtil; + +import java.lang.reflect.Method; +import java.util.Objects; + +/** + * kotlin.reflect.KParameter实例表示类
+ * 通过反射获取Kotlin中KParameter相关属性值 + * + * @author VampireAchao, Looly + */ +public class KParameter { + + private static final Method METHOD_GET_NAME; + private static final Method METHOD_GET_TYPE; + private static final Method METHOD_GET_JAVA_TYPE; + + static { + final Class kParameterClass = ClassLoaderUtil.loadClass("kotlin.reflect.KParameter"); + METHOD_GET_NAME = MethodUtil.getMethod(kParameterClass, "getName"); + METHOD_GET_TYPE = MethodUtil.getMethod(kParameterClass, "getType"); + + final Class kTypeClass = ClassLoaderUtil.loadClass("kotlin.reflect.jvm.internal.KTypeImpl"); + METHOD_GET_JAVA_TYPE = MethodUtil.getMethod(kTypeClass, "getJavaType"); + } + + private final String name; + private final Class type; + + /** + * 构造 + * + * @param kParameterInstance kotlin.reflect.KParameter实例对象 + */ + public KParameter(final Object kParameterInstance) { + this.name = MethodUtil.invoke(kParameterInstance, METHOD_GET_NAME); + final Object kType = MethodUtil.invoke(kParameterInstance, METHOD_GET_TYPE); + this.type = MethodUtil.invoke(kType, METHOD_GET_JAVA_TYPE); + } + + /** + * 获取参数名 + * + * @return 参数名 + */ + public String getName() { + return name; + } + + /** + * 获取参数类型 + * + * @return 参数类型 + */ + public Class getType() { + return type; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final KParameter that = (KParameter) o; + return Objects.equals(name, that.name) && Objects.equals(type, that.type); + } + + @Override + public int hashCode() { + return Objects.hash(name, type); + } + + @Override + public String toString() { + return "KParameter{" + + "name='" + name + '\'' + + ", type=" + type + + '}'; + } +} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/package-info.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/package-info.java new file mode 100644 index 000000000..2dd81e0f0 --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/kotlin/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * Kotlin反射相关封装,需引入: + *
    + *
  • kotlin-stdlib
  • + *
  • kotlin-reflect
  • + *
+ * + * @author VampireAchao, Looly + */ +package org.dromara.hutool.core.reflect.kotlin; diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/reflect/kotlin/KClassUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/reflect/kotlin/KClassUtilTest.java new file mode 100644 index 000000000..74b9aa87f --- /dev/null +++ b/hutool-core/src/test/java/org/dromara/hutool/core/reflect/kotlin/KClassUtilTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.core.reflect.kotlin; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.List; + +public class KClassUtilTest { + + @Test + void getConstructorTest() { + final List constructors = KClassUtil.getConstructors(TestKBean.class); + Assertions.assertEquals(1, constructors.size()); + + Assertions.assertEquals("kotlin.reflect.jvm.internal.KFunctionImpl", + constructors.get(0).getClass().getName()); + } + + @Test + void getParametersTest() { + final List constructors = KClassUtil.getConstructors(TestKBean.class); + + final List parameters = KClassUtil.getParameters(constructors.get(0)); + Assertions.assertEquals(3, parameters.size()); + + Assertions.assertEquals("id", parameters.get(0).getName()); + Assertions.assertEquals("name", parameters.get(1).getName()); + Assertions.assertEquals("country", parameters.get(2).getName()); + } +} diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/reflect/kotlin/TestKBean.kt b/hutool-core/src/test/java/org/dromara/hutool/core/reflect/kotlin/TestKBean.kt new file mode 100644 index 000000000..100867084 --- /dev/null +++ b/hutool-core/src/test/java/org/dromara/hutool/core/reflect/kotlin/TestKBean.kt @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.core.reflect.kotlin + +data class TestKBean(val id: String, var name: String?, var country: String?)