反射和注解html
反射机制是在运行状态中,对于任意一个类,都可以知道这个类的全部属性和方法;对于任意一个对象,都可以调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 Kotlin中使用反射功能所需的运行时组件做为单独的 JAR 文件(kotlin-reflect.jar)分发。这样作是为了减小不使用反射功能的应用程序所需的运行时库的大小。若是用Android Studio运行Kotlin项目,通常会在建立工程时,自动引入(kotlin-reflect.jar)java
//方式一
Class<?> clazz = User.class;
//方式二
Class<?> clazz = Class.forName("包名.User");
复制代码
//若是User是Kotlin的类
var user = User::class
//若是User是Java的类
var user = User::class.java
复制代码
在Kotlin中,用类名+两个冒号::
+class(若是是java类要在后面加上.java)表示获取这个类的对象。api
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);
复制代码
运行代码,获得结果:数组
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"))
复制代码
运行代码,获得结果:bash
在Kotlin中,能够用类名+两个冒号::
+函数名直接获取这个函数的对象;或者利用Java反射机制调用getMethod()
方法来获取函数的对象。微信
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));
复制代码
运行代码,获得结果:app
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))
复制代码
运行代码,获得结果:jvm
::
+属性名直接获取属性对象;或者经过Java反射机制获取属性的
get/set
方法来获取或修改属性值。
Java声明注解函数
public @interface MyAnnotation {
}
复制代码
Kotlin声明注解post
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
复制代码
注解类能够带有构造函数
annotation class MyAnnotation(val value: Int)
//使用
@MyAnnotation(1)
class Foo {
}
复制代码
public @interface MyAnnotation {
int value();
}
//使用
@MyAnnotation(1)
public class Foo {
}
复制代码
注解类的构造函数只容许下列参数类型:
注解和反射都是不少应用中使用到的技术,而本篇文章主要对比了注解和反射在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