推荐阅读:
学习Kotlin(一)为什么使用Kotlin
学习Kotlin(二)基本语法
学习Kotlin(三)类和接口
学习Kotlin(四)对象与泛型
学习Kotlin(五)函数与Lambda表达式
学习Kotlin(六)扩展与委托
学习Kotlin(七)反射和注解
学习Kotlin(八)其他技术
Kotlin学习资料总汇

目录

  • 1.反射
    1.1类引用
    1.2函数引用
    1.3属性引用
  • 2.注解
    2.1声明注解
    2.2构造函数

1.反射

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。Kotlin中使用反射功能所需的运行时组件作为单独的 JAR 文件(kotlin-reflect.jar)分发。这样做是为了减少不使用反射功能的应用程序所需的运行时库的大小。如果用Android Studio运行Kotlin项目,一般会在创建工程时,自动引入(kotlin-reflect.jar)

1.1类引用

  • Java代码
//方式一
Class<?> clazz = User.class;
//方式二
Class<?> clazz = Class.forName("包名.User");
  • Kotlin代码
//如果User是Kotlin的类var user = User::class
//如果User是Java的类var user = User::class.java

在Kotlin中,用类名+两个冒号::+class(如果是java类要在后面加上.java)表示获取这个类的对象。

1.2函数引用

  • Java代码
public class User {private String userName;public User(String userName) {super();this.userName = userName;}public void printUserName() {System.out.println(userName);}
}//获取User对象
Class<?> clazz = Class.forName("com.demo.czh.myapplication.User");
//获取带String参数的public构造函数
Constructor c=clazz.getDeclaredConstructor(String.class);
//创建User对象的实例
User user = (User) c.newInstance("Czh");
//根据方法名"printUserName"获取 method 对象
Method method = clazz.getDeclaredMethod("printUserName");
//通过 method 调用 invoke()方法,调用User里的 printUserName
method.invoke(user);

运行代码,得到结果:

  • Kotlin代码
class User(var userName: String) {fun printUserName() {println(userName)}
}//方式一
//获取printUserName函数对象
var p = User::printUserName
//调用invoke()函数执行printUserName函数
p.invoke(User("Czh"))//方式二
//利用Java反射机制调用getMethod()方法,并指定方法名字"printUserName"
var method = User::class.java.getMethod("printUserName")
//调用invoke()函数
method.invoke(User("Czh"))

运行代码,得到结果:

在Kotlin中,可以用类名+两个冒号::+函数名直接获取这个函数的对象;或者利用Java反射机制调用getMethod()方法来获取函数的对象。

1.3属性引用

  • Java代码
public class User {public String userName;
}//获取User对象
Class<?> clazz = Class.forName("com.demo.czh.myapplication.User");
//创建User对象的实例
User user = (User) clazz.newInstance();
//获取Field对象并指定属性名为"userName"
Field field = clazz.getField("userName");
//通过set()方法给userName赋值
field.set(user, "Czh");
//通过get()方法获取userName的值
System.out.println(field.get(user));

运行代码,得到结果:

  • Kotlin代码
class User {var userName: String = "Czh"get() = fieldset(value) {field = value}
}//方式一
var user = User()
//获取属性对象
var userName = User::userName
println(userName.get(user))
//设置属性值
userName.set(user, "James")
//获取属性值
println(userName.get(user))//方式二
//利用Java反射机制获取getUserName方法
var getName = User::class.java.getMethod("getUserName")
//利用Java反射机制获取setUserName方法
var setName = User::class.java.getMethod("setUserName", java.lang.String().javaClass)
//设置属性值
setName.invoke(user, "Harden")
//获取属性值
println(getName.invoke(user))

运行代码,得到结果:

在Kotlin中,可以用类名+两个冒号::+属性名直接获取属性对象;或者通过Java反射机制获取属性的get/set方法来获取或修改属性值。


2.注解

2.1注解声明

Java声明注解

public @interface MyAnnotation {
}

Kotlin声明注解

annotation class MyAnnotation

注解的附加属性可以通过用元注解标注注解类来指定:

  • @Target 指定可以用该注解标注的元素的可能的类型(类、函数、属性、表达式等);
  • @Retention 指定该注解是否存储在编译后的 class 文件中,以及它在运行时能否通过反射可见 (默认都是 true);
  • @Repeatable 允许在单个元素上多次使用相同的该注解;
  • @MustBeDocumented 指定该注解是公有 API 的一部分,并且应该包含在生成的 API 文档中显示的类或方法的签名中。

Java添加元注解

@Target(ElementType.METHOD)//表示可以在方法中使用
@Retention(RetentionPolicy.RUNTIME)//表示运行时注解
public @interface MyAnnotation {
}

Kotlin添加元注解

@Target(AnnotationTarget.FUNCTION)//表示可以在函数中使用
@Retention(AnnotationRetention.RUNTIME)//表示运行时注解
annotation class MyAnnotation

2.2构造函数

注解类可以带有构造函数

  • Kotlin代码
annotation class MyAnnotation(val value: Int)//使用
@MyAnnotation(1)
class Foo {
}
  • Java代码
public @interface MyAnnotation {int value();
}//使用
@MyAnnotation(1)
public class Foo {
}

注解类的构造函数只允许下列参数类型:

  • 对应于 Java 原生类型的类型(Int、 Long等);
  • 字符串;
  • 类(Foo::class);
  • 枚举;
  • 其他注解;
  • 上面已列类型的数组。
  • Kotlin中只允许用val声明参数
  • 当参数类型是其他注解时,该注解类的名字前面不能用@

总结

注解和反射都是很多应用中使用到的技术,而本篇文章主要对比了注解和反射在Java和Kotlin中写法的差别。

原文链接:https://juejin.im/post/5a98c613518825558722f7b8

学习Kotlin(七)反射和注解相关推荐

  1. Spring5学习(七):注解方式进行AOP操作 及 多种通知类型的测试

    先来介绍一下AOP操作中的几个术语: 1.连接点:指类里面可以被增强的方法 2.切入点:指实际被增强的方法 3.通知:指实际增强的逻辑部分 4.切面:把通知应用到切入点的过程 Spring框架一般都是 ...

  2. 学习Kotlin(八)其他技术

    推荐阅读: 学习Kotlin(一)为什么使用Kotlin 学习Kotlin(二)基本语法 学习Kotlin(三)类和接口 学习Kotlin(四)对象与泛型 学习Kotlin(五)函数与Lambda表达 ...

  3. 学习Kotlin(六)扩展与委托

    推荐阅读: 学习Kotlin(一)为什么使用Kotlin 学习Kotlin(二)基本语法 学习Kotlin(三)类和接口 学习Kotlin(四)对象与泛型 学习Kotlin(五)函数与Lambda表达 ...

  4. 学习Kotlin(五)函数与Lambda表达式

    推荐阅读: 学习Kotlin(一)为什么使用Kotlin 学习Kotlin(二)基本语法 学习Kotlin(三)类和接口 学习Kotlin(四)对象与泛型 学习Kotlin(五)函数与Lambda表达 ...

  5. 学习Kotlin(四)对象与泛型

    推荐阅读: 学习Kotlin(一)为什么使用Kotlin 学习Kotlin(二)基本语法 学习Kotlin(三)类和接口 学习Kotlin(四)对象与泛型 学习Kotlin(五)函数与Lambda表达 ...

  6. 学习Kotlin(三)类和接口

    推荐阅读: 学习Kotlin(一)为什么使用Kotlin 学习Kotlin(二)基本语法 学习Kotlin(三)类和接口 学习Kotlin(四)对象与泛型 学习Kotlin(五)函数与Lambda表达 ...

  7. 学习Kotlin(二)基本语法

    推荐阅读: 学习Kotlin(一)为什么使用Kotlin 学习Kotlin(二)基本语法 学习Kotlin(三)类和接口 学习Kotlin(四)对象与泛型 学习Kotlin(五)函数与Lambda表达 ...

  8. 学习Kotlin(一)为什么使用Kotlin

    推荐阅读: 学习Kotlin(一)为什么使用Kotlin 学习Kotlin(二)基本语法 学习Kotlin(三)类和接口 学习Kotlin(四)对象与泛型 学习Kotlin(五)函数与Lambda表达 ...

  9. Kotlin学习(七):函数

    Kotlin学习(七):函数 函数基本用法 Kotlin 函数必须用 fun 关键字开头,后面紧跟着函数名,以及一对小括号,小括号中是函数参数列表,如果函数有返回值,在小括号后面加冒号 (:),冒号后 ...

最新文章

  1. [转]GetProcAddress函数
  2. spring bean中scope=prototype“的作用
  3. Lync登录错误解决一例
  4. 【渝粤教育】 国家开放大学2020年春季 1032成本管理 参考试题
  5. 【C++grammar】动态类型转换、typeid与RTTI
  6. The credentials you provided during SQL Server 2008 install are invalid
  7. Java描述设计模式(24):备忘录模式
  8. xlwings复制sheet_Python操作Excel的Xlwings教程(六)
  9. 科密a1无法连接数据库_支持无线图传的稳定器——致迅A1-pro图传稳定器
  10. liveness 生存性/活性
  11. 廖雪峰python笔记
  12. C++编程之自定义日志类 ——log4cpp使用详解
  13. 赏析角度有哪些_几种分析的角度
  14. Python生成透明背景图片
  15. add-migration 多个DbContext
  16. 爱情智慧:结婚是什么感觉
  17. C++11 强类型枚举和普通枚举
  18. STM32开发(11)----CubeMX配置独立看门狗(IWDG)
  19. QAxObject来操作Excel的一些命令
  20. Linux命令详解之 mv

热门文章

  1. 机器学习笔记:auto encoder
  2. 文巾解题 面试题 01.03. URL化
  3. 文巾解题 620. 有趣的电影
  4. 以网易严选为例,人工智能实战系列之预训练语言模型
  5. tableau 如何发布到public
  6. 数据挖掘之离群点检测
  7. Python入门100题 | 第041题
  8. 关于更改linux源文件的问题(ubuntu)
  9. 颠覆传统的电商智能助理-阿里小蜜技术揭秘
  10. Example of ApplicationContextAware in Spring--转