kotlin

您所在的位置:网站首页 kotlin自学 kotlin

kotlin

#kotlin| 来源: 网络整理| 查看: 265

什么是反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。

反射的用途 在运行时判断任意一个对象所属的类; 在运行时构造任意一个类的对象; 在运行时判断任意一个类所具有的成员变量和方法; 在运行时调用任意一个对象的方法; 复制代码 简单使用 java反射

常用API

1.class getName(): 获取全类名,带包名 getSimpleName(): 获取类名 Class.forName("类名全路径"):返回类对象 getPackage(): 获取包名,有前缀package getClassLoader(): 获取类加载器 getClasses(): 获取该类中的公共内部类 getDeclaredClasses(): 获取该类中包含的所有类跟接口,包括非公共的 getSuper(): 获取继承父类类名 getInterfaces(): 获取接口 2.field getFields(): 获取公共字段 getDeclaredFields(): 获取类中的所有字段 getAnnotation(注解.class): 获取注解 3.construction getConstructions(): 获取公共的构造方法 getDeclaredConstructions(): 获取所有的构造方法 getDeclaredConstruction(Class... class): 根据参数的类型获取构造方法 4.method getMethods(): 获取公共方法 getDecleardMethods(): 获取所有的方法 getDeclaredMethod(String name, Class.... params): 根据方法名称跟参数列表获取方法 5.其它方法 isInterface(): 是否是接口 isAnnotation(): 判断是否是注解 isArray(): 是否是数组 isEnum(): 是否是枚举 isAnnotationPresent(Annotation.class): 判断是否有指定注解 6.反射相关方法 setAccessible(true): 设置暴力反射,无视限定符 Field.get(obj): 获取指定对象的field属性值 Field.set(obj, value): 设置obj对象的field属性为value值 Method.invoke(obj, Params.class):执行指定对象的该方法 复制代码

使用demo

private void Tests() { try { //通过Java反射机制得到类的包名和类名 Test1(); System.out.println("==============================================="); //验证所有的类都是Class类的实例对象 Test2(); System.out.println("==============================================="); //通过Java反射机制,用Class 创建类对象[这也就是反射存在的意义所在],无参构造 Test3(); System.out.println("==============================================="); //通过Java反射机制得到一个类的构造函数,并实现构造带参实例对象 Test4(); System.out.println("==============================================="); //通过Java反射机制操作成员变量, set 和 get Test5(); System.out.println("==============================================="); //通过Java反射机制得到类的一些属性: 继承的接口,父类,函数信息,成员信息,类型等 Test6(); System.out.println("==============================================="); //通过Java反射机制调用类中方法 Test7(); System.out.println("==============================================="); //通过Java反射机制获得类加载器 Test8(); System.out.println("==============================================="); } catch (Exception e) { e.printStackTrace(); } } /** * Demo1: 通过Java反射机制得到类的包名和类名 */ public static void Test1() { Person person = new Person(); System.out.println("Test1: 包名: " + person.getClass().getPackage().getName() + "," + "完整类名: " + person.getClass().getName()); } /** * Demo2: 验证所有的类都是Class类的实例对象 */ public static void Test2() throws ClassNotFoundException { //定义两个类型都未知的Class , 设置初值为null, 看看如何给它们赋值成Person类 Class class1 = null; Class class2 = null; //写法1, 可能抛出 ClassNotFoundException [多用这个写法] class1 = Class.forName("com.tuba.yuanyc.audiomanagerdemo.Person"); System.out.println("Test2:(写法1) 包名: " + class1.getPackage().getName() + "," + "完整类名: " + class1.getName()); //写法2 class2 = Person.class; System.out.println("Test2:(写法2) 包名: " + class2.getPackage().getName() + "," + "完整类名: " + class2.getName()); } /** * Demo3: 通过Java反射机制,用Class 创建类对象[这也就是反射存在的意义所在] */ public static void Test3() throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class class1 = null; class1 = Class.forName("com.android.reflect.Person"); //由于这里不能带参数,所以你要实例化的这个类Person,一定要有无参构造函数 Person person = (Person) class1.newInstance(); person.setAge(26); person.setName("kaiven"); System.out.println("Test3: " + person.getName() + " : " + person.getAge()); } /** * Demo4: 通过Java反射机制得到一个类的构造函数,并实现创建带参实例对象 */ public static void Test4() throws ClassNotFoundException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { Class class1 = null; Person person1 = null; Person person2 = null; class1 = Class.forName("com.android.reflect.Person"); //得到一系列构造函数集合 Constructor[] constructors = class1.getConstructors(); try { person1 = (Person) constructors[0].newInstance(); } catch (InvocationTargetException e) { e.printStackTrace(); } person1.setAge(28); person1.setName("zhuk"); person2 = (Person) constructors[1].newInstance(29, "zhuk"); System.out.println("Test4: " + person1.getName() + " : " + person1.getAge() + " , " + person2.getName() + " : " + person2.getAge()); } /** * Demo5: 通过Java反射机制操作成员变量, set 和 get */ public static void Test5() throws IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException, InstantiationException, ClassNotFoundException { Class class1 = null; class1 = Class.forName("com.android.reflect.Person"); Object obj = class1.newInstance(); Field nameField = class1.getDeclaredField("name"); nameField.setAccessible(true); nameField.set(obj, "cyy"); System.out.println("Test5: 修改属性之后得到属性变量的值:" + nameField.get(obj)); } /** * Demo6: 通过Java反射机制得到类的一些属性: 继承的接口,父类,函数信息,成员信息,类型等 */ public static void Test6() throws ClassNotFoundException { Class class1 = null; class1 = Class.forName("com.android.reflect.Person"); //取得父类名称 Class superClass = class1.getSuperclass(); System.out.println("Test6: SuperMan类的父类名: " + superClass.getName()); System.out.println("==============================================="); Field[] fields = class1.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { System.out.println("类中的成员: " + fields[i]); } System.out.println("==============================================="); //取得类方法 Method[] methods = class1.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { System.out.println("Test6,取得SuperMan类的方法:"); System.out.println("函数名:" + methods[i].getName()); System.out.println("函数返回类型:" + methods[i].getReturnType()); System.out.println("函数访问修饰符:" + Modifier.toString(methods[i].getModifiers())); System.out.println("函数代码写法: " + methods[i]); } System.out.println("==============================================="); Class interfaces[] = class1.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { System.out.println("实现的接口类名: " + interfaces[i].getName()); } } /** * Demo7: 通过Java反射机制调用类方法 */ public static void Test7() throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException { Class class1 = null; class1 = Class.forName("com.android.reflect.SuperPerson"); System.out.println("Test7: \n调用无参方法fly():"); Method method = class1.getMethod("fly"); method.invoke(class1.newInstance()); System.out.println("调用有参方法smoke(int m):"); method = class1.getMethod("smoke", int.class); method.invoke(class1.newInstance(), 100); } /** * Demo8: 通过Java反射机制得到类加载器信息 *

* 在java中有三种类类加载器。 *

* 1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。 *

* 2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类 *

* 3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。 * * @throws ClassNotFoundException */ public static void Test8() throws ClassNotFoundException { Class class1 = null; class1 = Class.forName("com.android.reflect.SuperPerson"); String name = class1.getClassLoader().getClass().getName(); System.out.println("Test8: 类加载器类名: " + name); } 复制代码 kotlin反射

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.kotlin 复制代码

常用API

构造函数Constructor //返回这个类的所有构造器 public val constructors: Collection 成员变量和成员函数 //返回类可访问的所有函数和属性,包括继承自基类的,但是不包括构造器 override val members: Collection //返回类声明的所有函数 val KClass.declaredFunctions: Collection //返回类的扩展函数 val KClass.declaredMemberExtensionFunctions: Collection //返回类的扩展属性 val KClass.declaredMemberExtensionProperties: Collection //返回类自身声明的成员函数 val KClass.declaredMemberFunctions: Collection //返回类自身声明的成员变量(属性) val KClass.declaredMemberProperties: Collection 类相关信息 //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: Collection //13.判断一个对象是否为此类的实例 @SinceKotlin("1.1") public fun isInstance(value: Any?): Boolean //14.返回这个类的泛型列表 @SinceKotlin("1.1") public val typeParameters: List //15.类其直接基类的列表 @SinceKotlin("1.1") public val supertypes: List //16.返回类所有的基类 val KClass.allSuperclasses: Collection //17.返回类的伴生对象companionObject val KClass.companionObject: KClass? 复制代码

使用demo

package com.yxhuang.androiddailydemo.reflect import kotlin.reflect.KMutableProperty1 import kotlin.reflect.full.* import kotlin.reflect.jvm.isAccessible /** * Created by yxhuang * Date: 2021/7/30 * Description: */ //定义注解 annotation class Anno @Deprecated("该类已经不推荐使用") @Anno class ReflectA(val name: String) { companion object{ const val TAG = "ReflectA" fun show(){ } } var age: Int = 0 constructor() : 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: Double get() = 3.14 fun main() { println("Hello word") val clazz = ReflectA::class println(clazz) println("ReflectA 的全部构造器如下:") clazz.constructors.forEach { println(it) } println("ReflectA 的主构造器如下:") println(clazz.primaryConstructor) println(" ") //通过functions属性获取该KClass对象所对应类的全部方法 val funs = clazz.functions println("ReflectA 的全部方法如下:") funs.forEach { println(it) } println(" ") //通过 declaredFunctions 属性获取该KClass对象声明的全部方法 val funs2 = clazz.declaredFunctions println("ReflectA 本身声明的全部方法如下:") funs2.forEach { println(it) } println(" ") //通过 memberExtensionFunctions 属性获取全部扩展方法 val exetensionFunctions = clazz.memberExtensionFunctions println("ReflectA 声明的扩展方法如下:") exetensionFunctions.forEach { println(it) } println(" ") //通过decaredMemberProperties获取全部成员属性 var memberProperties = clazz.declaredMemberProperties println("ReflectA 本身声明的成员属性如下:") memberProperties.forEach { println(it) } println(" ") //通过memberExtensionProperties属性获取该KClass对象的全部扩展属性 var exProperties = clazz.memberExtensionProperties println("ReflectA 本身声明的扩展属性如下:") exProperties.forEach { println(it) } println(" ") //通过annotations属性获取该KClass对象所对应类的全部注解 val anns = clazz.annotations println("ReflectA 的全部注解如下:") anns.forEach { println(it) } println("该KClass元素上的@Annot注解为:${clazz.findAnnotation()}") println(" ") //通过nestedClasses属性获取所对应的全部嵌套类 val inners = clazz.nestedClasses println("ReflectA 的全部内部类如下:") inners.forEach { println(it) } println(" ") //通过supertypes属性获取该类的所有父类型 println("KClassTest的父类型为:${clazz.supertypes}") println(" ") println("---------- companion 对象 ---------") // val companion = clazz.companionObject // 返回也是一个 KClass if (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.primaryConstructor val 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.declaredFunctions val 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.declaredMemberProperties val inst4 = clazz.createInstance() println("ReflectA 本身声明的成员属性如下:") memberProperties2.forEach { println(it) } println("inst4 name: ${inst4.name}") memberProperties2.forEach { if (it.name == "age") { it as KMutableProperty1 it.isAccessible = true it.set(inst4, 20) println(it.get(inst4)) } } } 复制代码

详细demo跳转此处观看

参考文章

blog.csdn.net/kai_zone/ar…

zhuanlan.zhihu.com/p/395105807



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3