Class对象:
Class对象是将class文件文件读入内存,并为之创建一个Class对象。类加载器首先会检查这个类的Class对象是否已被加载过,如果尚未加载,默认的类加载器就会根据类名查找对应的.class文件。获取Class对象的有三种方式:(1)直接通过对象来获取;(2)通过Class.forName来获取;(3)通过类直接获取。经常用到第二种方式,因为第一种和第三种都需要导入这个Class对象的包才可以用。第二种方式则不需要。代码如下
(这里新建一个密码类,方便演示)
package com.example.kotlinstudy.reflect
class Password constructor(password: String) {
private var strName : String = ""
private var strPassword: String = password
private val strKey = "123456"
val type = "RSA"
constructor(password: String, name: String) : this(password){
strName = name
}
private fun getKey() : String{
println("getKey $type$strKey")
return type + strKey
}
override fun toString(): String {
return "$strName : $strPassword : $type"
}
}
三种方式
val password = Password("123")
// 直接通过对象来获取(需要需要导入这个类的包,并且有实例对象)
val clazz1 = password.javaClass
// 通过Class.forName来获取(需要知道类的路径)
val clazz2 = Class.forName("com.example.kotlinstudy.reflect.Password")
// 通过类直接获取(需要导入这个类的包)
val clazz3 = Password::class.java
反射的一些实际应用:
- 修改类中私有属性字段的值
我们现在获取到一个Password对象,但是需要改变其私有变量strKey的值,从声明来看Password并未提供setter方法。这个时候,反射就可以帮上忙
// 模拟获取到一个Password类的实例
val password = Password("123")
// 直接通过对象来获取
val clazz1 = password.javaClass
val field = clazz1.getDeclaredField("strKey")
field.isAccessible = true
field.set(password, "654312")
println(password)
输出结果:
: 123 : RSA : 654312
备注:Class中有getField(fieldname)方法只能获取Public的字段Field。这里我们用getDeclaredField(fieldname)方法可以获取所有的字段Field。
- 调用类中私有属性的方法
// 模拟获取到一个Password类的实例
val password = Password("123")
// 直接通过对象来获取
val clazz1 = password.javaClass
val method = clazz1.getDeclaredMethod("getKey")
method.isAccessible = true
method.invoke(password)
输出结果:
getKey RSA123456
调用setKey方法,反射带参数的方法
// 模拟获取到一个Password类的实例
val password = Password("123")
// 直接通过对象来获取
val clazz1 = password.javaClass
val method = clazz1.getDeclaredMethod("setKey", String::class.java)
method.isAccessible = true
method.invoke(password, "111111")
输出结果:
setKey : 111111
- 对过Class对象new一个实例
// 通过Class.forName来获取
val clazz2 = Class.forName("com.example.kotlinstudy.reflect.Password")
var obj = clazz2.getConstructor(String::class.java).newInstance("147")
println(obj)
obj = clazz2.getConstructor(String::class.java, String::class.java).newInstance("147", "kotlin")
println(obj)
输出结果:
: 147 : RSA : 123456
kotlin : 147 : RSA : 123456
知识梳理
Class对象的方法:
// 获取所有公有方法
public Method[] getMethods()
// 获取某个公有方法
public Method getMethod(methodname: String)
// 获取所有的成员方法(包括私有)
public Method[] getDeclaredMehods()
// 获取某个成员方法(包括私有)
public Method getDeclaredMehod(methodname: String)
// 获取所有公有字段
public Field[] getFields()
// 获取某个公有字段
public Field getField(fieldname: String)
// 获取所有的字段(包括私有)
public Field[] getDeclaredFields()
// 获取某个字段(包括私有)
public Field getDeclaredField(fieldname: String)
Field对象的方法:
// obj是Class对象的实例,value是设置的值
field.set(obj: Object, value: Object)
Method对象的方法
// obj是Class对象的实例,agrs是对应方法的参数
method.invoke(obj: Object, Object... args)
网友评论