feat: add lazyClass, lazyClassOrNull functions

This commit is contained in:
2023-10-06 02:19:35 +08:00
parent 6f26fbc73e
commit bed0d42de0
2 changed files with 140 additions and 0 deletions

View File

@@ -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<T> internal constructor(
private val instance: Any,
private val initialize: Boolean,
private val loader: ClassLoaderInitializer?,
) {
/** 当前实例 */
private var baseInstance: Class<T>? = null
/**
* 获取非空实例
* @return [Class]<[T]>
*/
internal val nonNull get(): Class<T> {
if (baseInstance == null) baseInstance = when (instance) {
is String -> instance.toClass(loader?.invoke(), initialize) as Class<T>
is VariousClass -> instance.get(loader?.invoke(), initialize) as Class<T>
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<T>? {
if (baseInstance == null) baseInstance = when (instance) {
is String -> instance.toClassOrNull(loader?.invoke(), initialize) as? Class<T>?
is VariousClass -> instance.getOrNull(loader?.invoke(), initialize) as? Class<T>?
else -> error("Unknown lazy class type \"$instance\"")
}
return baseInstance
}
/**
* 非空实例
* @param instance 当前实例
* @param initialize 是否初始化
* @param loader [ClassLoader] 装载实例
*/
class NonNull<T> internal constructor(
instance: Any,
initialize: Boolean,
loader: ClassLoaderInitializer?,
) : LazyClass<T>(instance, initialize, loader) {
operator fun getValue(thisRef: Any?, property: KProperty<*>) = nonNull
}
/**
* 可空实例
* @param instance 当前实例
* @param initialize 是否初始化
* @param loader [ClassLoader] 装载实例
*/
class Nullable<T> internal constructor(
instance: Any,
initialize: Boolean,
loader: ClassLoaderInitializer?,
) : LazyClass<T>(instance, initialize, loader) {
operator fun getValue(thisRef: Any?, property: KProperty<*>) = nullable
}
}
/**
* 写出当前 [ClassLoader] 下所有 [Class] 名称数组
@@ -252,6 +327,68 @@ inline fun <reified T> String.toClassOrNull(loader: ClassLoader? = null, initial
inline fun <reified T> classOf(loader: ClassLoader? = null, initialize: Boolean = false) =
loader?.let { T::class.java.name.toClass(loader, initialize) as Class<T> } ?: 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<Any>(name, initialize, loader)
/**
* 懒装载 [Class]<[T]>
* @param name 完整类名
* @param initialize 是否初始化 [Class] 的静态方法块 - 默认否
* @param loader [ClassLoader] 装载实例 - 默认空 - 不填使用默认 [ClassLoader]
* @return [LazyClass.NonNull]<[T]>
*/
@JvmName("lazyClass_Generics")
inline fun <reified T> lazyClass(name: String, initialize: Boolean = false, noinline loader: ClassLoaderInitializer? = null) =
LazyClass.NonNull<T>(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<Any>(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<Any>(name, initialize, loader)
/**
* 懒装载 [Class]<[T]>
* @param name 完整类名
* @param initialize 是否初始化 [Class] 的静态方法块 - 默认否
* @param loader [ClassLoader] 装载实例 - 默认空 - 不填使用默认 [ClassLoader]
* @return [LazyClass.Nullable]<[T]>
*/
@JvmName("lazyClassOrNull_Generics")
inline fun <reified T> lazyClassOrNull(name: String, initialize: Boolean = false, noinline loader: ClassLoaderInitializer? = null) =
LazyClass.Nullable<T>(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<Any>(variousClass, initialize, loader)
/**
* 通过字符串类名使用指定的 [ClassLoader] 查找是否存在
* @param loader [Class] 所在的 [ClassLoader] - 不填使用默认 [ClassLoader]

View File

@@ -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