将静态变量从 Java 转换为 Kotlin [英] Convert static variables from Java to Kotlin

查看:27
本文介绍了将静态变量从 Java 转换为 Kotlin的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to convert the following code to Kotlin AND still have one of the classes (Foo) used by Java. What is the proper way of making this conversion?

原始 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 的自动转换

Auto conversion fo Foo to 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(错误:私有访问")

Bar class can no longer access C_ID or VALUES (error: "private access")

如果我将const"放在 C_ID 前面,它会起作用……但我不能对 VALUES 做同样的事情(const"只能用于原始或字符串)

if I put "const" in front of C_ID, it works... but I cannot do the same with VALUES ("const" can ONLY be used on primatives or String)

是否有不同的方式来执行此操作(这样 Java 代码和 Kotlin 代码都可以访问 Foo 中的所有内容)?

Is there a different way I should be doing this (so both Java code and Kotlin code can access everything in Foo)?

推荐答案

当前语义来自 Kotlin Beta 候选:

我们已经使生成纯字段(相对于 get/set 对)的策略更具可预测性:从现在开始,只有注释为 @JvmField 的属性lateinitconst 作为字段公开给 Java 客户端.旧版本使用启发式方法并无条件地在对象中创建静态字段,这与我们默认具有二进制兼容性友好的 API 的初始设计目标背道而驰.

@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.

此外,现在可以通过名称INSTANCE(而不是INSTANCE$)访问单例实例.

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

根据此和参考,Java 提供了三种处理 Kotlin object 属性的方法:

According to this and to the reference, there are three ways of working with properties of a Kotlin object from Java:

  • 使用Foo.INSTANCE.

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

By default, properties of object won't be static fields for Java, but Java can access the properties through Foo object instance -- Foo.INSTANCE.

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

@JvmStatic注解标记一个属性:

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

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

This will generate static getter for C_ID instead of Foo instance getter which will be accessible as Foo.getC_ID().

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

Use @JvmField annotation on property declaration:

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

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

This will make Kotlin compiler generate a static field for Java instead of property. Then in Java you can access it as a static field: Foo.C_ID.

但是如果没有像示例中的 all 这样的支持字段,它就无法在属性上工作.

But it won't work on properties without backing fields like all in your example.

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

For primitives, as you stated, one can use const which will have the same effect as @JvmField in terms of visibility in Java.

顺便说一句,说到方法,情况是一样的,都有@JvmStatic注解.

By the way, when it comes to methods, the situation is the same, and there is @JvmStatic annotation for them.

这篇关于将静态变量从 Java 转换为 Kotlin的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆