Kotlin
1.重载(方法名相同,参数不同(类型不同||数量不同))
Kotlin中是可以给参数添加默认值,使Kotlin自动重载:
(1) fun add(a: Int, b: Int = 2, c: Int = 3): Int {
return a + b + c
}
等价于 (2)(3)(4)
(2) fun add(a: Int): Int {
return a + 2 + 3
}
(3) fun add(a: Int, b: Int): Int {
return a + b + 3
}
(4) fun add(a: Int, b: Int,c: Int): Int {
return a + b + c
}
思考:函数(1)与(2)(3)能共存吗?如果可以那么add(1)调用的是函数(1)还是(2)?
注意:在kotlin中函数(1)相对于重载了三个函数,但是java调用此函数是只能使用三个参数,如:add(1,2,3)
为了兼容java,可使用@JvmOverloads注解函数使其在java调用是也含有同等的重载函数:例如
@JvmOverloads fun add(a: Int, b: Int = 2, c: Int = 3): Int {
return a + b + c
}
2.反射 需要引入反射jar包(implementation 'org.jetbrains.kotlin:kotlin-reflect:1.2.71')
(1):Kotlin 创建java私有构造对象
//反射创建java类对象
var People= People::class.java //获取java对应的class
.getConstructor(String::class.java) //获取一个参数的构造函数
.apply {
this.isAccessible = true //设置权限
}.newInstance("name") //调用一个参数的构造函数创建对象
(2):Kotlin 创建kotlin私有构造对象
//反射创建kotlin类对象
Person::class.constructors.forEach { //获取Person的所以构造函数 变量
it.isAccessible = true
val size = it.parameters.size
it.parameters.forEach {
val name = it.name
val type = it.type
val index = it.index
println("$name--$type--$index--$size")
}
if (size == 3) {
val call = it.call("name", "age", "sex")
Person::class.memberProperties.forEach {
it.isAccessible = true
it.javaField?.let {
if (it.name=="name") {
it.set(call,"setName")
}
}
}
println("${call.name}--${call.age}--${call.sex}")
}
(3)设置私有成员变量
//根据(2)中创建了对象 call
Person::class.memberProperties.forEach { //获取Person所以成员属性并遍历
it.isAccessible = true //设置访问权限
it.javaField?.let { //获取java反射代理函数
if (it.name == "name") {
it.set(call, "setName") //代理设置call name属性
}
}
}
(4)调用私有函数
//根据(2)中创建了对象 call
Person::class.declaredFunctions.forEach { //获取Person的函数
it.isAccessible = true //设置访问权限
println("declaredFunctions:${it.name}")
if (it.name=="add") {
val invoke = it.call(call, 1, 2, 3) //代理函数并执行call.add()
//val invoke = it.javaMethod?.invoke(call, 1, 2, 3) //获取java反射代理函数并执行call.add()
println("result:$invoke")
}
}
//伴生类函数调用
Person::class.companionObject?.declaredFunctions?.forEach {
println("companionObject:${it.name}")
it.isAccessible = true
if (it.name=="companion") {
val call1 = it.call(Person, 1, 2, 3)
println("companionObject result:$call1")
}
}
Person
open class Person private constructor(private var name: String, var age: String = "age", var sex: String = "sex") {
public fun add(a: Int, b: Int = 0, c: Int = 0): Int {
return a + b + c
}
override fun toString(): String {
return "Person(name='$name', age='$age', sex='$sex')"
}
companion object {
private fun companion(a: Int, b: Int = 0, c: Int = 0): Int {
return a + b + c
}
}
}
补充
如果Class是私有如何获取对应的class与kclass
获取私有java类的 class
java 类可用Class.forName 获取类对应的class 代替上文中的People::class.java
var peopleClass= Class.forName("com.zhanpple.People")
var people= forName.getConstructor(String::class.java).apply {
this.isAccessible = true
}.newInstance("a")
获取私有kotlin类的class
kotlin中没有KClass.forName函数 但是可以利用java中的Class.forName()和扩展函数Class<T>.kotlin来获取KClass
val personClass= Class.forName("com.zhanpple.Person").kotlin
personClass.constructors.forEach {
it.isAccessible = true
val size = it.parameters.size
it.parameters.forEach {
val name = it.name
val type = it.type
val index = it.index
println("$name--$type--$index--$size")
}
...
...
}