From bed0d42de0bd81fe2265e626e52e2c62533f885e Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Fri, 6 Oct 2023 02:19:35 +0800 Subject: [PATCH] feat: add lazyClass, lazyClassOrNull functions --- .../factory/ReflectionFactory.kt | 137 ++++++++++++++++++ .../finder/type/factory/TypeAliasFactory.kt | 3 + 2 files changed, 140 insertions(+) diff --git a/yukireflection-core/src/main/java/com/highcapable/yukireflection/factory/ReflectionFactory.kt b/yukireflection-core/src/main/java/com/highcapable/yukireflection/factory/ReflectionFactory.kt index 32a1972..f9134ca 100644 --- a/yukireflection-core/src/main/java/com/highcapable/yukireflection/factory/ReflectionFactory.kt +++ b/yukireflection-core/src/main/java/com/highcapable/yukireflection/factory/ReflectionFactory.kt @@ -33,6 +33,7 @@ package com.highcapable.yukireflection.factory import android.content.Context import com.highcapable.yukireflection.bean.CurrentClass import com.highcapable.yukireflection.bean.GenericClass +import com.highcapable.yukireflection.bean.VariousClass import com.highcapable.yukireflection.finder.base.rules.ModifierRules import com.highcapable.yukireflection.finder.classes.DexClassFinder import com.highcapable.yukireflection.finder.members.ConstructorFinder @@ -40,6 +41,7 @@ import com.highcapable.yukireflection.finder.members.FieldFinder import com.highcapable.yukireflection.finder.members.MethodFinder import com.highcapable.yukireflection.finder.tools.ReflectionTool import com.highcapable.yukireflection.finder.type.factory.ClassConditions +import com.highcapable.yukireflection.finder.type.factory.ClassLoaderInitializer import com.highcapable.yukireflection.finder.type.factory.ConstructorConditions import com.highcapable.yukireflection.finder.type.factory.FieldConditions import com.highcapable.yukireflection.finder.type.factory.MethodConditions @@ -69,6 +71,79 @@ import java.lang.reflect.Field import java.lang.reflect.Member import java.lang.reflect.Method import java.lang.reflect.ParameterizedType +import kotlin.reflect.KProperty + +/** + * 懒装载 [Class] 实例 + * @param instance 当前实例 + * @param initialize 是否初始化 + * @param loader [ClassLoader] 装载实例 + */ +open class LazyClass internal constructor( + private val instance: Any, + private val initialize: Boolean, + private val loader: ClassLoaderInitializer?, +) { + + /** 当前实例 */ + private var baseInstance: Class? = null + + /** + * 获取非空实例 + * @return [Class]<[T]> + */ + internal val nonNull get(): Class { + if (baseInstance == null) baseInstance = when (instance) { + is String -> instance.toClass(loader?.invoke(), initialize) as Class + is VariousClass -> instance.get(loader?.invoke(), initialize) as Class + else -> error("Unknown lazy class type \"$instance\"") + } + return baseInstance ?: error("Exception has been thrown above") + } + + /** + * 获取可空实例 + * @return [Class]<[T]> or null + */ + internal val nullable get(): Class? { + if (baseInstance == null) baseInstance = when (instance) { + is String -> instance.toClassOrNull(loader?.invoke(), initialize) as? Class? + is VariousClass -> instance.getOrNull(loader?.invoke(), initialize) as? Class? + else -> error("Unknown lazy class type \"$instance\"") + } + return baseInstance + } + + /** + * 非空实例 + * @param instance 当前实例 + * @param initialize 是否初始化 + * @param loader [ClassLoader] 装载实例 + */ + class NonNull internal constructor( + instance: Any, + initialize: Boolean, + loader: ClassLoaderInitializer?, + ) : LazyClass(instance, initialize, loader) { + + operator fun getValue(thisRef: Any?, property: KProperty<*>) = nonNull + } + + /** + * 可空实例 + * @param instance 当前实例 + * @param initialize 是否初始化 + * @param loader [ClassLoader] 装载实例 + */ + class Nullable internal constructor( + instance: Any, + initialize: Boolean, + loader: ClassLoaderInitializer?, + ) : LazyClass(instance, initialize, loader) { + + operator fun getValue(thisRef: Any?, property: KProperty<*>) = nullable + } +} /** * 写出当前 [ClassLoader] 下所有 [Class] 名称数组 @@ -252,6 +327,68 @@ inline fun String.toClassOrNull(loader: ClassLoader? = null, initial inline fun classOf(loader: ClassLoader? = null, initialize: Boolean = false) = loader?.let { T::class.java.name.toClass(loader, initialize) as Class } ?: T::class.java +/** + * 懒装载 [Class] + * @param name 完整类名 + * @param initialize 是否初始化 [Class] 的静态方法块 - 默认否 + * @param loader [ClassLoader] 装载实例 - 默认空 - 不填使用默认 [ClassLoader] + * @return [LazyClass.NonNull] + */ +fun lazyClass(name: String, initialize: Boolean = false, loader: ClassLoaderInitializer? = null) = + lazyClass(name, initialize, loader) + +/** + * 懒装载 [Class]<[T]> + * @param name 完整类名 + * @param initialize 是否初始化 [Class] 的静态方法块 - 默认否 + * @param loader [ClassLoader] 装载实例 - 默认空 - 不填使用默认 [ClassLoader] + * @return [LazyClass.NonNull]<[T]> + */ +@JvmName("lazyClass_Generics") +inline fun lazyClass(name: String, initialize: Boolean = false, noinline loader: ClassLoaderInitializer? = null) = + LazyClass.NonNull(name, initialize, loader) + +/** + * 懒装载 [Class] + * @param variousClass [VariousClass] + * @param initialize 是否初始化 [Class] 的静态方法块 - 默认否 + * @param loader [ClassLoader] 装载实例 - 默认空 - 不填使用默认 [ClassLoader] + * @return [LazyClass.NonNull] + */ +fun lazyClass(variousClass: VariousClass, initialize: Boolean = false, loader: ClassLoaderInitializer? = null) = + LazyClass.NonNull(variousClass, initialize, loader) + +/** + * 懒装载 [Class] + * @param name 完整类名 + * @param initialize 是否初始化 [Class] 的静态方法块 - 默认否 + * @param loader [ClassLoader] 装载实例 - 默认空 - 不填使用默认 [ClassLoader] + * @return [LazyClass.Nullable] + */ +fun lazyClassOrNull(name: String, initialize: Boolean = false, loader: ClassLoaderInitializer? = null) = + lazyClassOrNull(name, initialize, loader) + +/** + * 懒装载 [Class]<[T]> + * @param name 完整类名 + * @param initialize 是否初始化 [Class] 的静态方法块 - 默认否 + * @param loader [ClassLoader] 装载实例 - 默认空 - 不填使用默认 [ClassLoader] + * @return [LazyClass.Nullable]<[T]> + */ +@JvmName("lazyClassOrNull_Generics") +inline fun lazyClassOrNull(name: String, initialize: Boolean = false, noinline loader: ClassLoaderInitializer? = null) = + LazyClass.Nullable(name, initialize, loader) + +/** + * 懒装载 [Class] + * @param variousClass [VariousClass] + * @param initialize 是否初始化 [Class] 的静态方法块 - 默认否 + * @param loader [ClassLoader] 装载实例 - 默认空 - 不填使用默认 [ClassLoader] + * @return [LazyClass.Nullable] + */ +fun lazyClassOrNull(variousClass: VariousClass, initialize: Boolean = false, loader: ClassLoaderInitializer? = null) = + LazyClass.Nullable(variousClass, initialize, loader) + /** * 通过字符串类名使用指定的 [ClassLoader] 查找是否存在 * @param loader [Class] 所在的 [ClassLoader] - 不填使用默认 [ClassLoader] diff --git a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/type/factory/TypeAliasFactory.kt b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/type/factory/TypeAliasFactory.kt index fa66452..c97684b 100644 --- a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/type/factory/TypeAliasFactory.kt +++ b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/type/factory/TypeAliasFactory.kt @@ -37,6 +37,9 @@ import com.highcapable.yukireflection.finder.members.ConstructorFinder import com.highcapable.yukireflection.finder.members.FieldFinder import com.highcapable.yukireflection.finder.members.MethodFinder +/** 定义 [ClassLoader] 装载实例方法体类型 */ +internal typealias ClassLoaderInitializer = () -> ClassLoader? + /** 定义 [DexClassFinder] 方法体类型 */ internal typealias ClassConditions = DexClassFinder.() -> Unit