标签: kotlin-reflect

绑定类引用返回协变类型的目的是什么?

我正在玩反思,我出现了这个问题.通过::class语法使用绑定类引用时,我得到一个协变的KClass类型:

fun <T> foo(entry: T) {
    with(entry::class) {
       this // is instance of KClass<out T>
    }
}
Run Code Online (Sandbox Code Playgroud)

正如我可以从文档中学习的那样,这将返回对象的确切类型,以防它是子类型的实例T,因此是方差修饰符.但是这会阻止检索在T类中声明的属性并获取它们的值(这是我正在尝试做的)

fun <T> foo(entry: T) {
    with(entry::class) {
       for (prop in memberProperties) {
           val v = prop.get(entry) //compile error: I can't consume T
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

我发现一个解决方案是javaClass.kotlin在对象引用上使用扩展函数,而不是使用不变类型:

fun <T> foo(entry: T) {
    with(entry.javaClass.kotlin) {
       this // is instance of KClass<T>
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,我在运行时获得了确切的类型,并且可以使用该类型.

有趣的是,如果我使用超类型而不是泛型,使用后一种方法我仍然可以访问正确的类型,而不需要方差:

class Derived: Base()

fun foo(entry: Base) {
    with(entry.javaClass.kotlin) {
       println(this == …
Run Code Online (Sandbox Code Playgroud)

kotlin kotlin-reflect

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

如何使用 Kotlin 中的默认构造函数参数值实例化对象?

我有默认值的数据类。

data class Project(
    val code: String,
    val name: String,
    val categories: List<String> = emptyList())
Run Code Online (Sandbox Code Playgroud)

当某些值为空时,Java 反射无法实例化类。我得到了例外

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method Project.<init>, parameter categories
Run Code Online (Sandbox Code Playgroud)

这是因为java.lang.reflect.Constructor<T>.instantiateClass方法需要不为空的参数。

我有类型信息,我有构造函数定义,但我不确定如何调用构造函数以便它使用默认值(这些值来自数据库并且categories可以是null)。有没有办法在 Kotlin 中实现这一目标?

reflection kotlin kotlin-reflect kotlin-null-safety

5
推荐指数
2
解决办法
1514
查看次数

Kotlin-reflect和android gradle插件3.1.0

我在我的项目中使用org.jetbrains.kotlin:kotlin-reflect库(包含在gradle依赖项中).

该应用程序一直没有任何问题,但在将android gradle插件升级到最新版本3.1.0之后,应用程序开始在一台设备上崩溃(Nexus 5,Android 4.4.3).日志如下:

E/AndroidRuntime:FATAL EXCEPTION:kotlin.jvm.KotlinReflectionNotSupportedError:在运行时找不到Kotlin反射实现.确保你在kotlin.jvm.internal.ClassReference.error(ClassReference.kt:86)的类路径中有kotlin-reflect.jar,位于kotlin.jvm.internal.ClassReference.getSimpleName(ClassReference.kt:23)

我认为这不是预期的行为,但也许有人找到了解决方法/解决方案?

现在我被迫将android gradle插件降级到3.0.1以防止应用程序崩溃.

====================

我试图重新创建导致崩溃的环境,但是我没有设法重现崩溃.因为这只发生在较旧的Android版本(pre-L)上,并且在升级引入一些dex优化的android gradle插件之后,我的猜测是它在某种程度上相关.

====================

对于将此问题标记为重复的人:

我不确定是否可以更清楚:其他票证是否缺少依赖性.我在build.gradle中有kotlin反映依赖.此外,我的应用程序适用于较高的Android版本以及将android gradle插件降级到3.0.1之后.如果缺少依赖项,则无法使用任何版本的android gradle插件.因此,其他问题的答案对此无效.

android kotlin kotlin-reflect

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

以允许可为空类型并使用该类型参数声明“KClass&lt;T&gt;”的方式声明函数泛型类型参数

KClass定义为public interface KClass<T : Any> : KDeclarationContainer, KAnnotatedElement, KClassifier

这很棘手,因为 a 的类String?应该是KClass<String>,但不可能获得。

给出下面的 3 个示例(它们本质上应该执行相同的工作),其中 1 个无法编译,其他返回相同的运行时类型。

inline fun <reified T> test1(): Any = T::class
inline fun <reified T: Any> test2(): KClass<T> = T::class
inline fun <reified T> test3(): KClass<T> = T::class // does not compile

test1<String?>() // class kotlin.String
test1<String>() // class kotlin.String
test2<String?>() // does not compile
test2<String>() // class kotlin.String
Run Code Online (Sandbox Code Playgroud)

问题的重点是问:如何获得 的运行时行为和test1的编译时行为(和安全性)test2

编辑:问题的最后一个附录是另一个示例,它演示了获取可为空类型的类的问题。

inline fun <reified T> …
Run Code Online (Sandbox Code Playgroud)

kotlin kotlin-reflect

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

Kotlin 中 KProperty1 的通用扩展

我有以下代码:

import kotlin.reflect.KProperty1


infix fun <T, R> KProperty1<T, R>.eq(value: R) {
    println(this.name + " = $value")
}

infix fun <T, R> KProperty1<T, R>.eq(value: KProperty1<T, R>) {
    println(this.name + " = " + value.name)
}

data class Person(val age: Int, val name: String, val surname: String?)

fun main() {
    Person::age eq 1  // Valid. First function
    Person::name eq "Johan"  // Valid. First function
    Person::name eq Person::name  // Valid. Second function
    Person::age eq 1.2f  // Valid, but it shouldn't be. First function …
Run Code Online (Sandbox Code Playgroud)

reflection kotlin kotlin-reflect

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

IllegalStateException:无法分析:java.lang.AssertionError:注释树尚未归属:@kotlin.Metadata

在 Android Studio 3.4.1 中从 Kotlin 1.3.21 更新到 1.3.30+ 时,我们收到以下构建错误:

e: java.lang.IllegalStateException: failed to analyze: java.lang.AssertionError: annotation tree hasn't been attributed yet: @kotlin.Metadata(mv = {1, 1, 15}, bv = {1, 0, 3}, k = 1, d1 = {"\u0000$\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\b\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\b&\u0018\u0000*\b\b\u0000\u0010\u0001*\u00020\u00022\b\u0012\u0004\u0012\u0002H\u00010\u0003B\u001f\u0012\u0006\u0010\u0004\u001a\u00020\u0005\u0012\b\b\u0001\u0010\u0006\u001a\u00020\u0007\u0012\u0006\u0010\b\u001a\u00020\t\u00a2\u0006\u0002\u0010\n\u00a8\u0006\u000b"}, d2 = {"Lde/thermomess/field/ui/viewholder/BaseViewHolder;", "T", "", "Lcom/xroot/android/ui/recyclerview/RecyclerViewHolder;", "context", "Landroid/content/Context;", "layoutResId", "", "parent", "Landroid/view/ViewGroup;", "(Landroid/content/Context;ILandroid/view/ViewGroup;)V", "app_betaDebug"})
Run Code Online (Sandbox Code Playgroud)

@kotlin.Metadata 背后的所有内容都不同,但在此之前它保持不变。对于 Kotlin 1.3.21 及更早版本,一切工作正常。

我们使用 @kotlin.Metadata 来检查一个类是否是 Gson TypeAdapterFactory 的 Kotlin 类

private val Class<*>.isKotlinClass: Boolean
    get() = declaredAnnotations.find { it.annotationClass.java.name == "kotlin.Metadata" } != null
Run Code Online (Sandbox Code Playgroud)

以及通过混淆规则跳过自定义注释 …

android kotlin kotlin-reflect

5
推荐指数
0
解决办法
2038
查看次数

我在 Kotlin KClass 中看不到私有成员

我正在开发一个使用反射的库,我想操作给定 KClass 的所有属性/函数。

使用该KClass::members属性,我可以操作所有可访问的成员(根据文档),即:公共、内部和受保护的字段、属性和函数。但我看不到私人的。

使用 Java 反射,我可以使用 来查看所有字段(包括私有字段)Class.getDeclaredFields(),同样我可以使用 来查看私有方法Class.getDeclaredMethods()

有没有办法使用 kotlin 反射 API 来做到这一点?

kotlin kotlin-reflect

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

为什么 Kotlin 接口“未开放”?

在 Kotlin 1.4.30 中,当我输入

open interface I
Run Code Online (Sandbox Code Playgroud)

Kotlin 编译器警告我modifier 'open' is redundant for 'interface'。这完全有道理:当然接口是开放的,否则它们将毫无用处。

但是,反射库似乎与此相矛盾:

interface I
println(I::class.isOpen) // prints 'false'
Run Code Online (Sandbox Code Playgroud)

这有什么意义?的KDocisOpen非常简短:

true 如果这个类是开放的。

Kotlin 中“开放”的确切定义是什么? 我认为这意味着“开放被该文件之外的类进行子类型化的可能性”。

reflection kotlin kotlin-reflect

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

Kotlin 1.6.0 的 proguard / R8 删除了数据类元数据

我有一个包含一些数据类的包,我尝试使用 Kotlin 反射在运行时访问构造函数clazz.primaryConstructor,一切都按预期工作,但是当我启用 R8 时,数据类元数据被删除,例如当我检查它是否KClass isData返回 false 时并且主构造函数也为 null,这仅在启用 R8 时发生。我尝试了一切,包括@keep向所有数据类添加注释并添加规则以将所有内容保留在模型包中,我还添加了这些规则

-keep class kotlin.reflect.**

-keep class kotlin.Metadata { *; }
Run Code Online (Sandbox Code Playgroud)

但仍然没有运气,知道出了什么问题或如何解决这个问题吗?

示例回购协议

提前致谢。

android proguard kotlin kotlin-reflect android-r8

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

如何通过反思获得kotlin包

Kotlin反射库定义了KDeclarationContainer哪个Represents an entity which may contain declarations of any other entities, such as a class or a package.

this::class返回KClass,扩展KDeclarationContainer,但我如何得到父KDeclarationContainer(a KPackage?)

kotlin kotlin-reflect

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