1.什么是元编程
元数据:描述数据的数据。
元编程:操作元数据的编程。
程序即是数据:访问描述程序的数据,如通过反射获取类型信息。
数据即是程序:将这些数据转化成对应的程序,也就是所谓代码生成。
总结:
元编程是指操作元数据的编程。
元编程可以消除某些样板代码。
常见的元编程技术:反射、宏、模板元编程、路径依赖类型。
2.Kotlin与Java反射
Kotlin 的 KClass 和 Java 的 Class 可以看做同一个含义的类型,并且可以通过 .java 和 .kotlin 方法在 KClass 和 Class 之间互相转化。
Kotlin 的 KCallable 和 Java 的 AccessiableObject 都可以理解为可调用元素。Java 中构造方法为一个独立的类型,而 Kotlin 则统一作为 KFunction 处理。
Kotlin 的 KProperty 和 Java 的 Field 不太相同。Kotlin 的 KProperty 通常指相应的 Getter 和 Setter 整体作为一个 KProperty,而 Java 的 Filed 通常仅仅指字段本身。
3.Kotlin的KClass
属性或函数名称
含义
isCompanion
是否是伴生对象
isData
是否数据类
isSealed
是否密封类
objectInstance
object实例
companionObjectInstance
伴生对象实例
declaredMemberExtensionFunctions
扩展函数
declaredMemberExtensionProperties
扩展属性
memberExtensionFunctions
本类及超类扩展函数
memberExtensionProperties
本类及超类扩展属性
starProjectedType
泛型通配类型
4.Kotlin的KCallable
Kotlin 把 Class 中的属性(Property)、函数(Function)、甚至构造函数都看作 KCallable,因为他们是可调用的,都是 Class 的成员。
API
描述
isAbstract:Boolean
此 KCallable 是否为抽象的
isFinal:Boolean
此 KCallable 是否为final
isOpen:Boolean
此 KCallable 是否为open
name:String
此 KCallable 的名称
parameters:List
调用此 KCallable 需要的参数
returnType:KType
此 KCallable 的返回类型
typeParameters:List
此 KCallable 的类型参数
visibility:KVisibility?
此 KCallable 的可见性
call(vararg args: Any?): R
给定参数调用此 KCallable
5.获取参数信息
函数的参数:KParameter
API
描述
index:Int
返回该参数在参数列表里面的index
isOptinoal:Boolean
该参数是否为Optional
isVararg:Boolean
该参数是否为Vararg
kind:Kind
该参数的kind
name:String?
该参数的名称
type:KType
该参数的类型
函数的返回值:KType
API
描述
arguments:List
该类型的类型参数
classifier:KClassifier?
该类型在类声明层面的类型(忽略类型参数)
isMarkedNullable:Boolean
该类型是否标记为可空类型
类型参数:KTypeParameter
6.Kotlin的注解
创建注解:annotation class XXX
和Java一样,注解的参数只能是常量,并且仅支持下列类型:
与Java对应的基本类型;
字符串;
Class对象(KClass或者Java的Class);
其他注解;
上述类型数组。注意基本类型数组需要指定为对应的XXXArray,例如IntArray。
Kotlin与Java 的元注解:
Kotlin
Java
注解用途
kotlin.annotation.Retention
java.lang.annotation.Retention
用于何处
kotlin.annotation.Target
java.lang.annotation.Target
文档
kotlin.annotation.Documented
java.lang.annotation.Documented
可重复
kotlin.annotation.Repeatable
java.lang.annotation.Repeatable
Kotlin目前不支持 Inherited 注解。
Retention取值:
取值
说明
SOURCE
仅在源代码中存在,编译后class文件中不包含该注解信息
CLASS
class文件中存在该注解,但不能被发射读取
RUNTIME
注解信息保存在class文件中并且可以在运行时通过反射获取
Target取值:
Kotlin
Java
说明
CLASS
TYPE
作用于类
ANNOTATION_CLASS
ANNOTATION_TYPE
作用于注解本身(即元注解)
TYPE_PARAMETER
TYPE_PARAMETER
作用于类型参数
PROPERTY
-
作用于属性
FIELD
FIELD
作用于字段(属性通常包含字段Getter以及Setter)
LOCAL_VARIABLE
LOCAL_VARIABLE
作用于局部变量
VALUE_PARAMETER
-
作用于val参数
CONSTRUCTOR
CONSTRUCTOR
作用于构造函数
FUNCTION
METHOD
作用于函数
PROPERTY_GETTER
-
作用于Getter
PROPERTY_SETTER
-
作用于Setter
TYPE
TYPE_USE
作用于类型
EXPRESSION
-
作用于表达式
FILE
PACKAGE
作用于文件开头/包声明
TYPEALIAS
-
作用于类型别名
构造函数:
注解可以有接受参数的构造函数。允许的参数类型有:
对应于 Java 原生类型的类型(Int、 Long等);
字符串;
类(::class);
枚举;
其他注解;
上面已列类型的数组。
注解使用处目标:
@file,@property,@field,@get,@set,@receiver,@param,@setparam,@delegate
7.获取注解信息
通过反射获取注解信息
注解处理器