门户网站广告的特点有,重庆招投标信息网官网,哪个网站平面设计做的好,h5网站怎么做的吗1 反射简介
反射机制是在运行状态中#xff0c;对于任意一个类#xff0c;都能够知道这个类的所有属性和方法#xff0c;对于任意一个对象#xff0c;都能够调用它的任意一个方法和属性。
1.1 Kotlin反射 我们对比Kotlin和Java的反射类图。
1.1.1 Kotlin反射常用的数据结…1 反射简介
反射机制是在运行状态中对于任意一个类都能够知道这个类的所有属性和方法对于任意一个对象都能够调用它的任意一个方法和属性。
1.1 Kotlin反射 我们对比Kotlin和Java的反射类图。
1.1.1 Kotlin反射常用的数据结构
数据结构概念及使用说明KType描述未擦除的类型或泛型参数等例如 MapString,Int;可通过 typeof 或者以下类型获取对应的父类、属性、函数参数等KClass描述对象的实际类型不包含泛型参数例如Map可通过对象、类型名直接获得KProperty描述属性可通过属性引用、属性所在类的 KClass 获取KFunction描述函数可通过函数引用、函数所在类的 KClass 获取
1.2 对比Java反射 1.2.1 Kotlin与Java 反射优缺点 Java 反射 优点:无需引入额外依赖首次使用速度相对较快 缺点: 无法访问 Kotlin 语法特性需对 Kotlin 生成的字节码足够了解 Kotlin 反射 优点: 支持访问 Kotlin 几乎所有特性API 设计更友好 缺点:引入 Kotin 反射库(2.5MB编译后 400KB)首次调用慢
1.3 反射用途
在运行时判断任意一个**对象所属的类**在运行时构造任意一个**类的对象**在运行时判断任意一个**类所具有的成员变量和方法**在运行时调用任意一个**对象的方法**
2 Kotlin反射
2.1 反射使用
Kotlin 的反射需要集成 org.jetbrains.kotlin:kotlin-reflect 仓库版本保持与 Kotlin 一致。
implementation org.jetbrains.kotlin:kotlin-reflect:$kotlin_version在Kotlin中字节码对应的类是kotlin.reflect.KClass因为Kotlin百分之百兼容Java所以Kotlin中可以使用Java中的反射但是由于Kotlin中字节码.class对应的是KClass类所以如果想要使用Java中的反射需要首先获取Class的实例在Kotlin中可以通过以下两种方式来获取Class实例。
//1.通过实例.javaClass
var hello HelloWorld()
hello.javaClass//2.通过类Kclass类的.java属性
HelloWorld::class.java获取了Class实例就可以调用上面介绍的方法获取各种在Java中定义的类的信息了。
当然Kotlin中除了可以使用Java中的反射以外还可以使用Kotlin中声明的一些方法当然同Java中反射一样想要使用这些方法先要获取Kclass对象在Kotlin中可以通过以下两种方式获取KClass实例。 //1.通过类::class的方式获取Kclass实例
val clazz1: KClass* HelloWorld::class
//2.通过实例.javaClass.kotlin获取Kclass实例
var hello HelloWorld()
val clazz2 hello.javaClass.kotlin2.2 常用API
2.2.1 构造函数Constructor
//返回这个类的所有构造器
public val constructors: CollectionKFunctionT2.2.2 成员变量和成员函数 //返回类可访问的所有函数和属性包括继承自基类的但是不包括构造器override val members: CollectionKCallable*//返回类声明的所有函数val KClass*.declaredFunctions: CollectionKFunction*//返回类的扩展函数val KClass*.declaredMemberExtensionFunctions: CollectionKFunction*//返回类的扩展属性val T : Any KClassT.declaredMemberExtensionProperties: CollectionKProperty2T, *, *//返回类自身声明的成员函数val KClass*.declaredMemberFunctions: CollectionKFunction*//返回类自身声明的成员变量属性val T : Any KClassT.declaredMemberProperties: CollectionKProperty1T, *2.2.3 类相关信息
//1.返回类的名字
public val simpleName: String?
//2.返回类的全包名
public val qualifiedName: String?
//3.如果这个类声明为object则返回其实例否则返回null
public val objectInstance: T?
//4.返回类的可见性
SinceKotlin(1.1)
public val visibility: KVisibility?
//5.判断类是否为final类在Kotlin中类默认是final的除非这个类声明为open或者abstract)
SinceKotlin(1.1)
public val isFinal: Boolean
//6.判断类是否是open的(abstract类也是open的表示这个类可以被继承
SinceKotlin(1.1)
public val isOpen: Boolean
//7.判断类是否为抽象类
SinceKotlin(1.1)
public val isAbstract: Boolean
//8.判断类是否为密封类密封类:用sealed修饰其子类只能在其内部定义
SinceKotlin(1.1)
public val isSealed: Boolean
//9.判断类是否为data类
SinceKotlin(1.1)
public val isData: Boolean
//10.判断类是否为成员类
SinceKotlin(1.1)
public val isInner: Boolean
//11.判断类是否为companion object
SinceKotlin(1.1)
public val isCompanion: Boolean
//12.返回类中定义的其他类包括内部类(inner class声明的)和嵌套类(class声明的)
public val nestedClasses: CollectionKClass*//13.判断一个对象是否为此类的实例
SinceKotlin(1.1)
public fun isInstance(value: Any?): Boolean
//14.返回这个类的泛型列表
SinceKotlin(1.1)
public val typeParameters: ListKTypeParameter
//15.类其直接基类的列表
SinceKotlin(1.1)
public val supertypes: ListKType
//16.返回类所有的基类
val KClass*.allSuperclasses: CollectionKClass*
//17.返回类的伴生对象companionObject
val KClass*.companionObject: KClass*?2.3 使用demo
package com.yvan.demo.reflectimport kotlin.reflect.KMutableProperty1
import kotlin.reflect.full.*
import kotlin.reflect.jvm.isAccessible//定义注解
annotation class AnnoDeprecated(该类已经不推荐使用)
Anno
class ReflectA(val name: String) {companion object{const val TAG ReflectAfun show(){}}var age: Int 0constructor() : this(ReflectA_)constructor(name: String, age: Int) : this(name) {this.age age}fun print(str: String) {println(ReflectA print str $str)}fun sayHi(): String {println(ReflectA sayHi)return sayHi}class InnerClass
}// 拓展方法
fun ReflectA.exfun() {println(exfun)
}// 拓展属性
val ReflectA.foo: Doubleget() 3.14fun main() {println(Hello word)val clazz ReflectA::classprintln(clazz)println(ReflectA 的全部构造器如下)clazz.constructors.forEach {println(it)}println(ReflectA 的主构造器如下)println(clazz.primaryConstructor)println( )//通过functions属性获取该KClass对象所对应类的全部方法val funs clazz.functionsprintln(ReflectA 的全部方法如下)funs.forEach { println(it) }println( )//通过 declaredFunctions 属性获取该KClass对象声明的全部方法val funs2 clazz.declaredFunctionsprintln(ReflectA 本身声明的全部方法如下)funs2.forEach { println(it) }println( )//通过 memberExtensionFunctions 属性获取全部扩展方法val exetensionFunctions clazz.memberExtensionFunctionsprintln(ReflectA 声明的扩展方法如下)exetensionFunctions.forEach { println(it) }println( )//通过decaredMemberProperties获取全部成员属性var memberProperties clazz.declaredMemberPropertiesprintln(ReflectA 本身声明的成员属性如下)memberProperties.forEach { println(it) }println( )//通过memberExtensionProperties属性获取该KClass对象的全部扩展属性var exProperties clazz.memberExtensionPropertiesprintln(ReflectA 本身声明的扩展属性如下)exProperties.forEach { println(it) }println( )//通过annotations属性获取该KClass对象所对应类的全部注解val anns clazz.annotationsprintln(ReflectA 的全部注解如下)anns.forEach { println(it) }println(该KClass元素上的Annot注解为${clazz.findAnnotationAnno()})println( )//通过nestedClasses属性获取所对应的全部嵌套类val inners clazz.nestedClassesprintln(ReflectA 的全部内部类如下)inners.forEach { println(it) }println( )//通过supertypes属性获取该类的所有父类型println(KClassTest的父类型为${clazz.supertypes})println( )println(---------- companion 对象 ---------) //val companion clazz.companionObject // 返回也是一个 KClassif (companion ! null){println(companion $companion)companion.declaredMemberProperties.forEach {println(companion declaredMemberProperties: $it)}companion.declaredFunctions.forEach {println(companion declaredFunctions: $it)}}println( )println(---------- 创建对象 ---------)println( )println(createInstance 创建实例)// createInstance() 方法调用无参数的构造器创建实例val inst2 clazz.createInstance()println(inst2.name)println(inst2.age)println( )// primaryConstructor 主构造函数val cons1 clazz.primaryConstructorval inst1 cons1?.call(hello reflect) // 参入参数println(inst1)println(inst1 inst1?.name)println( )println(第一个构造函数)val cons2 clazz.constructors.first()println(cons2)println( )println(-------调用方法------)val funs3 clazz.declaredFunctionsval inst3 clazz.createInstance()println(ReflectA 本身声明的全部方法如下)funs3.forEach { println(it) }for (f in funs3) {if (f.name sayHi) {f.call(inst3)}if (f.name print) {f.call(inst3, 反射打印)}}println(\n)println(-------访问属性------)//通过decaredMemberProperties获取全部成员属性val memberProperties2 clazz.declaredMemberPropertiesval inst4 clazz.createInstance()println(ReflectA 本身声明的成员属性如下)memberProperties2.forEach { println(it) }println(inst4 name: ${inst4.name})memberProperties2.forEach {if (it.name age) {it as KMutableProperty1ReflectA, Intit.isAccessible trueit.set(inst4, 20)println(it.get(inst4))}}
}3 Kotlin反射总结
反射是一种在运行时动态访问对象属性和方法的方式而不需事先确定这些属性是什么。 一般来说当你访问一个对象的方法或者属性时程序的源代码会因用一个具体的声明编译器将静态解析这个引用并确保这个声明是存在的。但有时候你要编写能够使用任意类型的对象的代码或者只能在运行时才能确定要访问的方法和属性的名称。