从Java到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() = field
        set(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中写法的差别。

参考文献:
Kotlin语言中文站、《Kotlin程序开发入门精要》

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


更多精彩文章请扫描下方二维码关注微信公众号"AndroidCzh":这里将长期为您分享原创文章、Android开发经验等! QQ交流群: 705929135

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值