Kotlin中反射機(jī)制的原理是什么

本篇文章給大家分享的是有關(guān)Kotlin中反射機(jī)制的原理是什么,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。

創(chuàng)新互聯(lián)公司于2013年創(chuàng)立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都做網(wǎng)站、網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元拉孜做網(wǎng)站,已為上家服務(wù),為拉孜各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:028-86922220

Java中的反射機(jī)制,使得我們可以在運(yùn)行期獲取Java類的字節(jié)碼文件中的構(gòu)造函數(shù),成員變量,成員函數(shù)等信息。這一特性使得反射機(jī)制被常常用在框架中,想要比較系統(tǒng)的了解Kotlin中的反射,先從Java的反射說(shuō)起。

Java中的反射

通常我們寫(xiě)好的.java源碼文件,經(jīng)過(guò)javac的編譯,最終生成了.class字節(jié)碼文件。這些字節(jié)碼文件是與平臺(tái)無(wú)關(guān)的,使用時(shí)通過(guò)Classloader去加載這些.class字節(jié)碼文件,從而讓程序按照我們編寫(xiě)好的業(yè)務(wù)邏輯運(yùn)行。Java的反射主要是從這些.class文件中獲取我們想要得到的內(nèi)容,那么Java中的反射能夠得到哪些內(nèi)容呢?

獲取Class對(duì)象

Java是面向?qū)ο蟮恼Z(yǔ)言,同樣的.class字節(jié)碼文件也不例外,想要獲取.class文件中的內(nèi)容,就要先獲取.class文件對(duì)應(yīng)的Class對(duì)象。Java中獲取Class對(duì)象的方式有三種。

//1.Class.forName("類名字符串") (注意:類名字符串必須是全稱,包名+類名)
Class baseInfo = Class.forName("top.sguotao.ReflectionJava");
 //2.類名.class
Class object = Object.class;
//3.實(shí)例對(duì)象.getClass()
Class date = (new Date()).getClass();
Class testclass = this.getClass();

獲取類的構(gòu)造函數(shù)Constructor

獲取Class對(duì)象之后,就可以獲取其中的構(gòu)造函數(shù),從而去創(chuàng)建實(shí)例對(duì)象。類的構(gòu)造函數(shù)對(duì)應(yīng)java.lang.reflect.Constructor。獲取構(gòu)造函數(shù)歸納起來(lái)有以下五種方式:

 // 1.獲取參數(shù)列表是parameterTypes,訪問(wèn)控制符是public的構(gòu)造函數(shù)
 public Constructor getConstructor(Class[] parameterTypes)

 // 2.獲取所有訪問(wèn)控制符是public的構(gòu)造函數(shù)
 public Constructor[] getConstructors()

 // 3.獲取參數(shù)列表是parameterTypes,并且是類自身聲明的構(gòu)造函數(shù),訪問(wèn)控制符包含public、protected和private的函數(shù)。
 public Constructor getDeclaredConstructor(Class[] parameterTypes)

 //4.獲取類自身聲明的全部的構(gòu)造函數(shù),訪問(wèn)控制符包含public、protected和private的函數(shù)。
 public Constructor[] getDeclaredConstructors()

 //5.如果類聲明在其它類的構(gòu)造函數(shù)中,返回該類所在的構(gòu)造函數(shù),如果存在則返回,不存在返回null
 public Constructor getEnclosingConstructor()

獲取類的成員變量

類的成員變量對(duì)應(yīng)的是java.lang.reflect.Field,獲取成員變量歸納起來(lái)有以下四種方式:

 //1.獲取“名稱是name”的public的成員變量(包括從基類繼承的、從接口實(shí)現(xiàn)的所有public成員變量)
 public Field getField(String name)

 //2.獲取全部的public成員變量(包括從基類繼承的、從接口實(shí)現(xiàn)的所有public成員變量)
 public Field[] getFields()

 //3.獲取“名稱是name”,并且是類自身聲明的成員變量,包含public、protected和private成員變量。
 public Field getDeclaredField(String name)

 //4.獲取全部的類自身聲明的成員變量,包含public、protected和private成員變量。
 public Field[] getDeclaredFields()

獲取類的成員函數(shù)

類的成員函數(shù)對(duì)應(yīng)的是java.lang.reflect.Method,獲取成員函數(shù)歸納起來(lái)有下面5種方式:

// 1.獲取函數(shù)名是name,參數(shù)是parameterTypes的public的函數(shù)(包括從基類繼承的、從接口實(shí)現(xiàn)的所有public函數(shù))
 public Method getMethod(String name, Class[] parameterTypes)

 //2.獲取全部的public的函數(shù)(包括從基類繼承的、從接口實(shí)現(xiàn)的所有public函數(shù))
 public Method[] getMethods()

 //3.獲取函數(shù)名name,參數(shù)是parameterTypes,并且是類自身聲明的函數(shù),包含public、protected和private方法。
 public Method getDeclaredMethod(String name, Class[] parameterTypes)

 //4.獲取全部的類自身聲明的函數(shù),包含public、protected和private方法。
 public Method[] getDeclaredMethods()

 //5.如果這個(gè)類是其它類中某個(gè)方法的內(nèi)部類,調(diào)用getEnclosingMethod()就是這個(gè)類所在的方法;若不存在,返回null。
 public Method getEnclosingMethod()

獲取類的其它信息

獲取類的注解信息,對(duì)應(yīng)的是java.lang.annotation.Annotation接口,獲取類的注解信息歸納起來(lái)有下面3種方法:

//1.獲取類的annotationClass類型的注解 (包括從基類繼承的、從接口實(shí)現(xiàn)的所有public成員變量)
public Annotation<A> getAnnotation(Class annotationClass)

//2.獲取類的全部注解 (包括從基類繼承的、從接口實(shí)現(xiàn)的所有public成員變量)
public Annotation[] getAnnotations()

//3.獲取類自身聲明的全部注解 (包含public、protected和private成員變量)
public Annotation[] getDeclaredAnnotations()

獲取類的接口和基類的信息,對(duì)應(yīng)的是java.lang.reflect.Type接口,獲取類的接口和基類信息有下面兩個(gè)方法:

 // 獲取實(shí)現(xiàn)的全部接口
public Type[] getGenericInterfaces()

// 獲取基類
public Type getGenericSuperclass()

獲取類的其它描述信息。

 //1.獲取類名
 public String getSimpleName()

 //2.獲取完整類名
 public String getName()

 //3.判斷類是不是枚舉類
 public boolean isEnum()

 //4.判斷obj是不是類的實(shí)例對(duì)象
 public boolean isInstance(Object obj)

 //5.判斷類是不是接口
 public boolean isInterface()

 //6.判斷類是不是本地類,所謂本地類,就是定義在方法內(nèi)部的類。
 public boolean isLocalClass()

 //7.判斷類是不是成員類,所謂成員類,就是常見(jiàn)的內(nèi)部類,是指不在代碼塊,構(gòu)造函數(shù)和成員方法中的內(nèi)部類。
 public boolean isMemberClass()

 //8.判斷類是不是基本類型。 基本類型,包括void和boolean、byte、char、short、int、long、float 和 double這幾種類型。
 public boolean isPrimitive()

Kotlin中的反射

在Kotlin中,字節(jié)碼對(duì)應(yīng)的類是kotlin.reflect.KClass,因?yàn)镵otlin百分之百兼容Java,所以Kotlin中可以使用Java中的反射,但是由于Kotlin中字節(jié)碼.class對(duì)應(yīng)的是KClass類,所以如果想要使用Java中的反射,需要首先獲取Class的實(shí)例,在Kotlin中可以通過(guò)以下兩種方式來(lái)獲取Class實(shí)例。

//1.通過(guò)實(shí)例.javaClass
var hello = HelloWorld()
hello.javaClass

 //2.通過(guò)類Kclass類的.java屬性
HelloWorld::class.java

獲取了Class實(shí)例,就可以調(diào)用上面介紹的方法,獲取各種在Java中定義的類的信息了。

當(dāng)然Kotlin中除了可以使用Java中的反射以外,還可以使用Kotlin中聲明的一些方法,當(dāng)然同Java中反射一樣,想要使用這些方法,先要獲取Kclass對(duì)象,在Kotlin中可以通過(guò)以下兩種方式獲取Kclass實(shí)例。

 //1.通過(guò)類::class的方式獲取Kclass實(shí)例
val clazz1: KClass<*> = HelloWorld::class
//2.通過(guò)實(shí)例.javaClass.kotlin獲取Kclass實(shí)例
var hello = HelloWorld()
val clazz2 = hello.javaClass.kotlin

獲取了Kclass實(shí)例之后,就可以調(diào)用Kotlin中聲明的一些關(guān)于反射的方法了,那么都有哪些方法呢?

構(gòu)造函數(shù)Constructor

Kotlin可以通過(guò)下面的方法,獲取所有的構(gòu)造函數(shù)。

//返回這個(gè)類的所有構(gòu)造器
public val constructors: Collection<KFunction<T>>

成員變量和成員函數(shù)

Kotlin中獲取成員變量和成員函數(shù)的方法有6個(gè)。

 //返回類可訪問(wèn)的所有函數(shù)和屬性,包括繼承自基類的,但是不包括構(gòu)造器
 override val members: Collection<KCallable<*>>
 //返回類聲明的所有函數(shù)
 val KClass<*>.declaredFunctions: Collection<KFunction<*>>
 //返回類的擴(kuò)展函數(shù)
 val KClass<*>.declaredMemberExtensionFunctions: Collection<KFunction<*>>
 //返回類的擴(kuò)展屬性
 val <T : Any> KClass<T>.declaredMemberExtensionProperties: Collection<KProperty2<T, *, *>>
 //返回類自身聲明的成員函數(shù)
 val KClass<*>.declaredMemberFunctions: Collection<KFunction<*>>
 //返回類自身聲明的成員變量(屬性)
 val <T : Any> KClass<T>.declaredMemberProperties: Collection<KProperty1<T, *>>

類相關(guān)信息

可以看到Kotlin反射中,可以獲取比Java反射更多的關(guān)于類的信息。

//1.返回類的名字
public val simpleName: String?
 //2.返回類的全包名
public val qualifiedName: String?
//3.如果這個(gè)類聲明為object,則返回其實(shí)例,否則返回null
public val objectInstance: T?
//4.返回類的可見(jiàn)性
@SinceKotlin("1.1")
public val visibility: KVisibility?
//5.判斷類是否為final類(在Kotlin中,類默認(rèn)是final的,除非這個(gè)類聲明為open或者abstract)
@SinceKotlin("1.1")
public val isFinal: Boolean
//6.判斷類是否是open的(abstract類也是open的),表示這個(gè)類可以被繼承
@SinceKotlin("1.1")
public val isOpen: Boolean
//7.判斷類是否為抽象類
@SinceKotlin("1.1")
public val isAbstract: Boolean
//8.判斷類是否為密封類,密封類:用sealed修飾,其子類只能在其內(nèi)部定義
@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.返回類中定義的其他類,包括內(nèi)部類(inner class聲明的)和嵌套類(class聲明的)
public val nestedClasses: Collection<KClass<*>>
 //13.判斷一個(gè)對(duì)象是否為此類的實(shí)例
@SinceKotlin("1.1")
public fun isInstance(value: Any?): Boolean
//14.返回這個(gè)類的泛型列表
@SinceKotlin("1.1")
public val typeParameters: List<KTypeParameter>
//15.類其直接基類的列表
@SinceKotlin("1.1")
public val supertypes: List<KType>
//16.返回類所有的基類
val KClass<*>.allSuperclasses: Collection<KClass<*>>
//17.返回類的伴生對(duì)象companionObject
val KClass<*>.companionObject: KClass<*>?

使用Kotin中反射注意的問(wèn)題

在Kotlin1.1中如果反射String,Map,List等類型時(shí),會(huì)拋出一個(gè)built-in Kotlin Types的異常,這是因?yàn)樵贙otlin1.1版本中還沒(méi)有對(duì)這些類型添加支持,在Kotlin1.2版本中,這個(gè)問(wèn)題已經(jīng)解決。

Kotlin關(guān)于反射的內(nèi)容都放在kotlin-reflect的jar包中,這個(gè)jar包有2.6M,對(duì)于移動(dòng)端開(kāi)發(fā),需要占用一定的內(nèi)存空間。

最后就是關(guān)于Kotlin反射的效率問(wèn)題,在Java中反射大概需要幾十微秒,在Kotlin就需要幾百甚至上千微秒,如果是通過(guò)反射訪問(wèn)對(duì)象或構(gòu)造屬性,甚至需要上萬(wàn)微秒,對(duì)此,官方給出的解釋是,現(xiàn)在還沒(méi)有精力進(jìn)行優(yōu)化,相信后續(xù)的版本中,效率問(wèn)題會(huì)有所改善。

以上就是Kotlin中反射機(jī)制的原理是什么,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

分享題目:Kotlin中反射機(jī)制的原理是什么
網(wǎng)站鏈接:http://muchs.cn/article34/ghjdse.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、App設(shè)計(jì)、軟件開(kāi)發(fā)、網(wǎng)站制作、網(wǎng)站排名標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)