我很难理解为什么一些公共功能显然不可用,尽管至少有一个其他功能可用.我举的例子来自Klaxon,但我怀疑我的预期和Kotlin的实际工作方式之间存在一些不匹配,而且它并不是Klaxon所特有的.

我在Ubuntu 16.04系统上使用命令行解释器.$j是包含Klaxon和许多其他内容的JAR文件的路径.如您所见,我正在使用Kotlin 1.9.20.文件foo.json仅包含{ "foo" : 1234, "bar": null, "baz": [11, 22, 33, 44] }.

$ kotlin -cp $j
Welcome to Kotlin version 1.9.20 (JRE 17.0.8+9-LTS-211)
Type :help for help, :quit for quit
>>> val x = com.beust.klaxon.Parser.default ().parse ("foo.json")
>>> val y = x as com.beust.klaxon.JsonObject
>>> y.get ("baz")
res2: kotlin.Any = JsonArray(value=[11, 22, 33, 44])

到目前为止,一切都很好;这正是我希望看到的.现在try 其他getSomething个函数.

>>> y.getKeys ()
error: unresolved reference: getKeys
y.getKeys ()
  ^
>>> y.getSize ()
error: unresolved reference: getSize
y.getSize ()
  ^
>>> y.getMap ()
error: unresolved reference: getMap
y.getMap ()
  ^

我不明白--我有一个期望类的对象,

>>> y::class
res6: kotlin.reflect.KClass<out com.beust.klaxon.JsonObject> = class com.beust.klaxon.JsonObject (Kotlin reflection is not available)
>>> 

我命名的方法都存在于类中,从我所知道的:

$ javap -cp $j com.beust.klaxon.JsonObject | grep get
  public final java.util.Map<java.lang.String, java.lang.Object> getMap();
  public java.util.Set<java.util.Map$Entry<java.lang.String, java.lang.Object>> getEntries();
  public java.util.Set<java.lang.String> getKeys();
  public int getSize();
  public java.util.Collection<java.lang.Object> getValues();
  public java.lang.Object get(java.lang.String);
  public final java.lang.Object get(java.lang.Object);

有人能解释一下我在这里看到了什么吗?我该怎么打getKeysgetMap等?

推荐答案

Java getters and setters are accessed as properties in Kotlin

当您使用javap自省类的形状时,您看到的是类的Java表示.因此,我们需要考虑Kotlin和Java之间的交互作用.

Kotlin与Java是完全可互操作的,但有时您在Kotlin中以不同的方式调用方法或访问属性.

具体地说,遵循Java getter和setter约定的方法(即以getset开头的方法)在Kotlin(documentation)中作为属性被访问.这就是您在javap分析中看到的getKeys()getSize()getMap()方法的情况.

因此,如果你在Kotlin try y.keysy.sizey.map,你应该会得到你预期的结果.

Note the original source was Kotlin

事实上,这里还有更多的步骤正在进行.我注意到第com.beust.klaxon.JsonObject类是用Kotlin 编写的(见GitHub).您可以在源代码中看到它有一个map属性,并且它从它实现的MutableMap接口继承了keyssize.这个源代码已经编译为JVM字节码,方法是将这些Kotlin属性表示为Java的getter和setter,遵循另一个发布的rule.

这与上面提到的用于从Kotlin调用Java代码的规则相反,这是我们所期望的;否则当从Kotlin使用编译的Kotlin库时会出现意想不到的结果(就像你一样).

Kotlin相关问答推荐

查看流数据和改进的HTTP请求的模型

如果启用了Flyway迁移,则不能具有配置属性';datources.default.架构-生成

如何在Docker中使用Selenium和chromedriver?

如何在 kotlin 中的数据类中为变量提供多种类型

Java/Kotlin中类似Rust般的注释编译?

kotlin 模式匹配如何像 scala 一样工作

如何在 Kotlin 中为类方法调用传递变量

Kotlin .如何用从 1 到 90 的 5 个唯一数字填充列表中的每一行?

在协程上下文中重新抛出异常

Kotlin:使用另一个列表和字母顺序对列表进行排序的有效方法

Kotlin - 协程未按预期执行

Kotlin:伴随对象内的函数扩展

Fragment的onDestroy()中是否需要将ViewBinding设置为null?

在粘贴时将 java 转换为 kotlin

`DataBindingUtil` 中的 `bind`、`inflate` 和 `setContentView` 有什么区别

带有迭代器函数的 Kotlin 无限序列

Android Room - error: Cannot figure out how to save this field into database

哪里可以找到aapt2日志(log)?

Android Studio 将 Java 转换为 Kotlin 错误无法推断此参数的类型

(kotlin的Moshi)@Json vs@field:Json