properties - 将静态变量从 Java 转换为 Kotlin

我正在尝试将以下代码转换为 Kotlin,并且仍然有 Java 使用的类 (Foo) 之一。进行这种转换的正确方法是什么?

原始Java:

public class Foo {
   public static final String C_ID = "ID";
   public static final String C_NAME = "NAME";
   public static final String[] VALUES = {"X", "Y", "Z"};

   public static String[] getAll() {
       return new String[] {C_ID, C_NAME};
   }
}

public class Bar {
    public void doStuff() {
        String var1 = Foo.C_ID;
        String[] array1 = Foo.VALUES;
        String[] array2 = Foo.getAll();
    }
}

Foo 到 Kotlin 的自动转换

object Foo {
    val C_ID = "ID"
    val C_NAME = "NAME"
    val VALUES = arrayOf("X", "Y", "Z")

    val all: Array<String>
        get() = arrayOf(C_ID, C_NAME)
}

问题:

Bar 类不能再访问 C_ID 或 VALUES(错误:“私有(private)访问”)

如果我将“const”放在 C_ID 前面,它可以工作......但我不能对 VALUES 做同样的事情(“const”只能用于基本体或字符串)

我应该以不同的方式执行此操作(因此 Java 代码和 Kotlin 代码都可以访问 Foo 中的所有内容)?

最佳答案

当前语义来自Kotlin Beta Candidate :

@JvmField and objects

We have made the strategy for generating pure fields (as opposed to get/set pairs) more predictable: from now on only properties annotated as @JvmField, lateinit or const are exposed as fields to Java clients. Older versions used heuristics and created static fields in objects unconditionally, which is against our initial design goal of having binary-compatibility-friendly APIs by default.

Also, singleton instances are now accessible by the name INSTANCE (instead of INSTANCE$).

据此和reference ,有三种方法可以使用 Java 中的 Kotlin object 的属性:

  • 使用 Foo.INSTANCE

    object的属性默认不会是Java的静态字段,但是Java可以通过Foo对象实例——Foo.INSTANCE访问属性.

    所以表达式将是 Foo.INSTANCE.getC_ID()

  • @JvmStatic 注解标记属性:

    object Foo {
        @JvmStatic val C_ID = "ID"
        //...
    }
    

    这将为 C_ID 生成静态 getter,而不是 Foo 实例 getter,后者可作为 Foo.getC_ID() 访问。

  • 在属性声明上使用@JvmField注解:

    object Foo {
        @JvmField val C_ID = "ID"
        //...
    }
    

    这将使 Kotlin 编译器为 Java 生成一个静态字段而不是属性。 然后在 Java 中,您可以将其作为静态字段访问:Foo.C_ID

    但它不适用于在您的示例中没有像 all 这样的支持字段的属性。

对于原语,如您所说,可以使用 const ,它在 Java 中的可见性方面与 @JvmField 具有相同的效果。

顺便说一句,当涉及到方法时,情况也是如此,并且有@JvmStatic注解。

https://stackoverflow.com/questions/35118514/

相关文章:

kotlin - 协程 : runBlocking vs coroutineScope

kotlin - 如何抑制未经检查的强制转换警告?

android - ArrayAdapter 使用 Kotlin android

java - Kotlin - 为非数据类生成 toString()

android - Kotlin 惰性属性和值重置 : a resettable lazy dele

kotlin - 什么是 Kotlin 模块?

android - Kotlin - 如何在 "lateinit"和 "nullable varia

kotlin - 如果事件是用 Kotlin 编写的,则按钮 onClick 属性为无

types - 为什么 Kotlin Array 不实现 Iterable

java - 如何使用 Maven 编译 Java+Kotlin 项目?