首页 > 其他分享 >kotlin 注解声明与使用

kotlin 注解声明与使用

时间:2022-11-04 11:37:01浏览次数:42  
标签:java kotlin 注解 实参 声明 class


前言

函数的调用需要知道函数所在的类,函数的入参个数和参数类型,注解和反射可以跳过这个限制,注解和反射可以编写事先未知的任意类代码。注解可以为类库赋予特定的语义,反射可以在运行时分析类的结构。

注解的声明与使用

注解允许你把额外的元数据关联到一个声明上,然后通过反射在运行时对元数据进行提取并使用。

要应用一个注解,以字符@作为名字前缀,放在注解前面

@Test
fun add(){

}

可以给注解提供实参

@Deprecated("removeAt(index) instead.",ReplaceWith("removeAt(index)"))
fun remove(index:Int){

}
//RelaceWith 也是一个注解
@Target()
@Retention(BINARY)
@MustBeDocumented
public annotation class ReplaceWith(val expression: String, vararg val imports: String)

注意:
注解的实参类型可以是基本类型、字符串、枚举、类引用、其他的注解类、数组等,在java中声明的注解类,命名为value的形参按需自动转换成的可变长度的形参,所以可以不用arrayOf函数就可以提供多个实参。

说明

表达式

把一个类指定为注解实参

@CustomAnnotation(MineClass::class)

另一个注解指定为实参

去掉注解的@,例如:ReplaceWith作为注解实参时,未加@前缀

把一个数组指定为实参

@RequestMapping(path=arrayof(“/foo”,“/bar”))

注解实参需要编译期确定,所以作为注解实参的属性需要使用const修饰,声明在文件的顶层或者object之中。

注解目标

说明元素中那些需要注解十分必要,因为kotlin源代码中的单个声明会对应成多个java声明元素。

{
var shengming=1
}
对应java
一个声明属性、一个getter,一个setter,编译时会自动生成这些模板代码

使用点目标声明被用来说明要注解的元素,而在java中只需要对字段或者函数添加@Rule注解就可以。

@get:Rule
  1. @get: 使用点目标
  2. Rule:注解名称
class foler{
@get:Rule
val folder=TemporaryFolder()
@Test
fun testDemo(){
...
}

Kotlin 支持的完整使用点目标完整列表

使用点目标

介绍

property

java的注解下不能应用

field

字段

get

属性getter

set

属性setter

receiver

接收者参数属性

param

构造方法属性

setparam

属性setter的参数

delegate

委托属性存储委托实例的字段

file

文件中声明的顶层函数和属性的类

kotlin中允许对任意的表达式应用注解

Tips:用注解可以控制javaApi的生成

注解

解释

@volatile

充当java关键字volatile

@strictfp

充当java关键字strictfp

@JvmName

改变由kotlin生成的java方法或字段的名称

@JvmStatic

把对象声明或者伴生对象的方法上,暴露成java static静态方法

@JvmOverloads

为带默认参数生成多个重载

@JvmField

应用于属性,暴露成没有访问器public 字段

声明注解

//不带参数的注解
annotation class MineAnnotation
//带参数的注解
annotation class MineAnnotation(val name:String)

注解类没有类主体,编译器也禁止。注解类用来关联到声明和表达式的元数据的结构,在java中声明同样的结构

public @interface MineAnnotation{
String value()
}

java中value在kotlin和java中均会被特殊对待。当你应用一个注解时,需要提供除value以外所有指定特性的显示名称.而kotli’n中不需要这么做。和普通构造函数一样用法。如果将java中声明的注解应用到kotlin中,必须对除value以外的所有实参使用命名实参法

//Target.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}

元注解:控制如何处理一个注解

元注解:可以应用到注解类上的注解被称作元注解

@Target(AnnotationTarget.PROPERTY)
annotation class JsonExclude

@Target元注解说明注解可以被应用的元素类型,AnnotationTarget 枚举值列出了可以应用注解的全部可能的目标,如果需要也可以同时声明多个AnnotationTarget目标

public enum class AnnotationTarget {
/** Class, interface or object, annotation class is also included */
CLASS,
/** Annotation class only */
ANNOTATION_CLASS,
/** Generic type parameter (unsupported yet) */
TYPE_PARAMETER,
/** Property */
PROPERTY,
/** Field, including property's backing field */
FIELD,
/** Local variable */
LOCAL_VARIABLE,
/** Value parameter of a function or a constructor */
VALUE_PARAMETER,
/** Constructor only (primary or secondary) */
CONSTRUCTOR,
/** Function (constructors are not included) */
FUNCTION,
/** Property getter only */
PROPERTY_GETTER,
/** Property setter only */
PROPERTY_SETTER,
/** Type usage */
TYPE,
/** Any expression */
EXPRESSION,
/** File */
FILE,
/** Type alias */
@SinceKotlin("1.1")
TYPEALIAS
}

如何定义自己的元注解:ANNOTATION_CLASS

@Target(AnnotationTarget.ANNOTATION_CLASS)
annotation class myAnnotation

使用
@myAnnotation
annotation class MYBinding

注意: PROPERTY注解只在kotlin中可用,如果java中要可用需要同时声明
@Target(AnnotationTarget.FIELD,AnnotationTarget.PROPERTY),对于@Retention注解来声明注解是否会存储到.class文件,运行时是否可以通过反射类访问它,在java中会在.class保留但是无法运行时获取,在kotlin中默认为在.class中存储注解信息,在Runtime保留注解。

使用类作为注解参数

使用场景就是在对一个嵌套类进行反序列化时候,定制使用那个类型实参来进行赋值

class School{
//学校名
val schoolName
//办公室,使用类名称::class 来引用一个类
@DeserializeInterface(xxx::class)
var office:Office
}

注解的声明

annotation class DeserializeInterface(val targetClass:Kclass<out Any>)

注意这里的泛型修饰符out的用法,表示保留子类型的关系。即协变,Kclass可以接收的类型包括Any即Any衍生出来的任何子类型都可以作为Kclass的泛型类型。如果不使用out进行修饰的话,则只能传递Any作为Kclass的泛型类型。

使用泛型类做注解

interface ValueSeriailizer<T>{

fun toJsonValue(value:T):Any?

fun fromJsonValue(jsonValue:Any?):T

}

data class Persion{

@CustomAnnotation(DateSerializer::class)
val date:Date
}

//@CustomAnnotation 如何声明
annotaion class CustomAnnotation(val serializerClass:Kclass<ValueSerializer<*>>)

之后调用时候需要保证serializerClass调用时输入的实参需要实现ValueSerializer接口类

Kclass<out ValueSerializer<*>>

out修饰符,表示接收任何实现了ValueSerializer接口,不只是ValueSerializer::class
ValueSerializer<*>中的 * ,可以序列化任何值

这里提供一个通用的写法对于需要用注解类作为实参传递的注解类:

//如果YourClassName 有自己的实参类型,就用*代替
Kclass<out YourClassName>

总结

  1. java中应用注解语法和kotlin几乎一摸一样
  2. kotlin让注解的目标范围比java更广,包括了文件和表达式
  3. 一个注解类的参数可以是基本类型、字符串、枚举、类引用、其他注解类实例、或者数据
  4. 使用点目标来处理kotlin这种一个声明产生多个字节码元素情况。var a=1 对应java中三种字节码元素。
  5. 注解类声明拥有一个主构造没有类主体构造方法中所有参数都被标示成val属性
  6. 元注解用来指定使用点目标、保留期模式、和其他注解的特性

引用
Kotlin实战第十章,注解部分


标签:java,kotlin,注解,实参,声明,class
From: https://blog.51cto.com/u_15861646/5823159

相关文章

  • Android kotlin泛型知识点梳理
    前言学习知识需要提前设立目标,带着问题学习才能有的放矢。无论是java的泛型还是kotlin语言的泛型均是写框架,写通用工具类神器。如果不熟悉泛型语法,开发过程中将会遇到很多奇......
  • Android kotlin 类委托 by,by lazy关键
    前言接触kotlin语言也有几年时间了。日常开发工作中也推荐使用kotlin,但是对于一些kotlin语言语法的细节没有进行系统学习。碎片的知识点让工作中屡屡碰壁,前些天开始学习comp......
  • 参数校验注解的实现
    /***请求参数注解处理类**@authord*@since2019/2/2014:32*/@ConfigurationpublicclassWebMvcConfigurationimplementsWebMvcConfigurer{@Ov......
  • 使用注解实现加解密方式
    /***对象隐私数据加解密工具类.**@authord*@since2018年05月22日*/publicfinalclassPrivacyDataHandler{privatestaticConcurrentHashMap<Str......
  • 注解 @Component及@Controller等,@Autowired,@Resource
    注解:对于DI使用注解,将不再需要在Spring配置文件中声明bean实例。Spring中使用注解,需要在原有Spring运行环境基础上再做一些改变。需要在Spring配置文件中配......
  • javaSE基础-注解与枚举类
    注解与枚举类注解1、jdk5.0新增的功能2、Annotation就是代码的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应处理,通过使用注解程序员在可以不改变原有......
  • SpringBoot自定义注解+异步+观察者模式实现业务日志保存
    一、前言我们在企业级的开发中,必不可少的是对日志的记录,实现有很多种方式,常见的就是基于AOP+注解进行保存,但是考虑到程序的流畅和效率,我们可以使用异步进行保存,在高并发情......
  • kotlin协程小记
    例子一:GlobalScope.launch(Dispatchers.Main){//开启子协程withContext(Dispatchers.IO){for(iin0until1000){}Log.d("Ma......
  • java Annotation 注解多参数
    javaAnnotation注解多参数使用注解格式注解的格式,通常情况下使用@符号开始,后面跟上对应的注解名称,以及注解参数和对应的值。@注解名称([{标识符=元素的值,标......
  • @RestController注解报红
    详情:创建springboot项目后,如图这两个位置报红   原因:pom文件中依赖的问题   解决:   ......