标签: kotlin-reflect

对属性设置器的方法引用

在不使用 kotlin-reflect 的情况下,如何获取对属性设置器的方法引用?

基本上,如果我用 java 方式编写代码,那就非常简单

fun setValue(i: Int) = Unit
val a: (Int) -> Unit = this::setValue
Run Code Online (Sandbox Code Playgroud)

但因为var value: Int我得到

var value = 1
val a: KMutableProperty0<Int> = this::value
Run Code Online (Sandbox Code Playgroud)

kotlin kotlin-reflect

4
推荐指数
1
解决办法
1560
查看次数

在 Kotlin 中组合/合并数据类

有没有办法在不指定所有属性的情况下合并 kotlin 数据类?

data class MyDataClass(val prop1: String, val prop2: Int, ...//many props)
Run Code Online (Sandbox Code Playgroud)

具有以下签名的函数:

fun merge(left: MyDataClass, right: MyDataClass): MyDataClass
Run Code Online (Sandbox Code Playgroud)

这个函数检查两个类的每个属性,它们不同的地方使用 left 参数来创建一个新的 MyDataClass。

使用 kotlin-reflect 或其他方法可以实现吗?

编辑:更清晰

这是我想要做的更好的描述

  data class Bob(
        val name: String?,
        val age: Int?,
        val remoteId: String?,
        val id: String)

@Test
fun bob(){

    val original = Bob(id = "local_id", name = null, age = null, remoteId = null)
    val withName = original.copy(name = "Ben")
    val withAge = original.copy(age = 1)
    val withRemoteId = original.copy(remoteId = "remote_id") …
Run Code Online (Sandbox Code Playgroud)

kotlin kotlin-reflect

4
推荐指数
2
解决办法
9973
查看次数

如何在Kotlin中获得KType?

我正在试验Kotlin中的反射功能,但我似乎无法理解如何获取KType值.

假设我有一个将短语映射到对象工厂的类.在模糊的情况下,用户可以提供type将搜索范围缩小到仅返回该类型对象(或某些子类型)的工厂的参数.

fun mapToFactory(phrase: Phrase,
          type: KType = Any::class): Any {...}
Run Code Online (Sandbox Code Playgroud)

type我需要接受几乎任何东西,包括Int从我的经验中看起来有点特别对待.默认情况下,它应该是类似的Any,这意味着"不排除任何工厂".

如何为默认值(或任何值)指定type

reflection kotlin kotlin-reflect

3
推荐指数
2
解决办法
3325
查看次数

在 Kotlin 中对具有默认参数的函数使用 callBy 时出错

我尝试使用默认参数值调用函数,而不在 Kotlin 中添加参数。

例如:

class Test {
    fun callMeWithoutParams(value : Double = 0.5) = value * 0.5

    fun callIt(name: String) = this.javaClass.kotlin
            .members.first { it.name == name }
            .callBy(emptyMap())
}

fun main(args: Array<String>) {
   println(Test().callIt("callMeWithoutParams"))
}
Run Code Online (Sandbox Code Playgroud)

我有一个例外:

Exception in thread "main" java.lang.IllegalArgumentException: No argument provided for a required parameter: instance of fun 
 Test.callMeWithoutParams(kotlin.Double): kotlin.Double
     at kotlin.reflect.jvm.internal.KCallableImpl.callDefaultMethod(KCallableImpl.kt:139)
    at kotlin.reflect.jvm.internal.KCallableImpl.callBy(KCallableImpl.kt:111)
    at Test.callIt(Main.kt:15)
    at MainKt.main(Main.kt:20)
Run Code Online (Sandbox Code Playgroud)

奇怪的是,该参数不是必需的,而是可选的......

reflection kotlin kotlin-reflect

3
推荐指数
1
解决办法
1632
查看次数

Kotlin 类应该有一个无参数的构造函数

我使用以下方法实例化我的对象:

val payInCurrency = Currency::class.createInstance()
            .copy(code = "GBP")
Run Code Online (Sandbox Code Playgroud)

但我在那一行遇到了一个例外:

java.lang.IllegalArgumentException: Class should have a single no-arg constructor: class com.abc.Currency
    at kotlin.reflect.full.KClasses.createInstance(KClasses.kt:281)
    at com.abc.MyInteractorTest.setUp(MyInteractorTest.kt:55)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
    at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
    at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
    at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:106)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
    at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:66)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
    at sun.reflect.GeneratedMethodAccessor35.invoke(Unknown …
Run Code Online (Sandbox Code Playgroud)

kotlin kotlin-reflect

3
推荐指数
1
解决办法
7058
查看次数

如何使用反射更改 kotlin 私有 val?

我可以使用反射访问私有 val 值,如下所示

fun main() {
    val mainClass = MainClass()
    val f = MainClass::class.memberProperties.find { it.name == "info" }
    f?.let {
        it.isAccessible = true
        val w = it.get(mainClass) as String
        println(w)
    }
}


class MainClass {
    private val info: String = "Hello"
}
Run Code Online (Sandbox Code Playgroud)

但是如果我想改变info,我怎么能用反射来做呢?

reflection kotlin kotlin-reflect

3
推荐指数
1
解决办法
2911
查看次数

Kotlin的反思:未知的类型参数

我正在对Kotlin的反思进行一些实验.

我试图通过其参数获得泛型类的反射对象.

在Java中,那将是一个ParameterizedType.

使用Java的反射API获取此类内容的方法有点复杂:创建泛型类的匿名子类,然后获取其超类型的第一个参数.

这是一个例子:

@Suppress("unused") @PublishedApi
internal abstract class TypeReference<T> {}

inline fun <reified T> jGeneric() =
    ((object : TypeReference<T>() {}).javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0]
Run Code Online (Sandbox Code Playgroud)

当我println(jGeneric<List<String?>>())打印时java.util.List<? extends java.lang.String>,考虑到Kotlin List使用声明站点out方差并且Java类型没有可空性概念,这是合乎逻辑的.

现在,我希望获得相同类型的结果,但使用Kotlin反射API(当然,它包含可空性信息).

当然,List<String>::class因为它产生了一个不能工作KClass.我正在寻找一个KType.

但是,当我尝试这个:

inline fun <reified T> kGeneric() =
    (object : TypeReference<T>() {})::class.supertypes[0].arguments[0].type
Run Code Online (Sandbox Code Playgroud)

当我println(kGeneric<List<String?>>()),它打印[ERROR : Unknown type parameter 0],这是相当......好吧,虎头蛇尾;)

在Kotlin,我怎样才能得到一个KType反映List<String>

kotlin kotlin-reflect

1
推荐指数
1
解决办法
1517
查看次数

Kotlin - 从对象调用类方法

将尽可能简洁地保持这个......

我想在我的MainActivty类中有一个方法,比如updateUI().

我有另一个文件是一个名为FBManager的对象.该对象基本上拥有"静态"firebase访问方法..让我们说signInUser()

从Activity我调用FBManager.signInUser()...它做了一些逻辑并通过2个私有方法移动,在最后一个私有方法中,我想基本上调用MainActivity.updateUI()...

这不能完成,因为kotlin没有静态方法,并且不能使updateUI()静态.MainActivity().updateUI()编译但不正确,并且不想实例化新的MainActivity.最后,我想把活动传递给第一个构造函数,比如FBManager.signInUser(this)......但是在signInUser()之后,它会转到一个覆盖方法,它只能将一个包作为一个可选输入(我不是相信你可以把活动放到一个包中),因此我无法将活动引用传递给最终的私有方法.....

编辑:进一步阐述

object FBManager {

fun signInUser() {
// Create intent
startActivityForResult(intent)
}

override fun onActivityResult(some intent stuff) {
//Try catch block. In try block call
firebaseAuth(Google account)
}

fun firebaseAuth(acct: GoogleSignInAccount) {
//More logic and an .onCompleteListener

// Inside .onCompeteListener, which is the problem....
MainActivity.updateUI()
}
}
Run Code Online (Sandbox Code Playgroud)

为布局道歉......在我的手机上打字......

- 编辑 -

我希望所有这些都有意义,因为我是编程新手,并且发现很难解释我的问题(因为如果我真的理解它们,我可以想出一个解决方案......)

那么根据标题,还有其他方法可以做到这一点......从一个对象FBManager调用MainActivity中的方法吗?

android kotlin kotlin-reflect

1
推荐指数
1
解决办法
1950
查看次数

获取可空类型的类

我正在尝试String?在Kotlin反射练习中匹配nullable的类型:

data class Test(a: String, b: String?)
val test = Test("1", "2")
val properties = test::class.declaredMemberProperties
val propertyNames = properties.joinToString(",") { 
        when (it.returnType) {
            String?::class.createType() -> "string?"
            String::class.createType() -> "string"
            else -> throw Exception()
        }
}
Run Code Online (Sandbox Code Playgroud)

唉,它与错误而失败,Type in a class literal must not be nullableString?::class

reflection kotlin kotlin-reflect

1
推荐指数
1
解决办法
325
查看次数

标签 统计

kotlin ×9

kotlin-reflect ×9

reflection ×4

android ×1