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

查看:67
本文介绍了将静态变量从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();
    }
}

将fo 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)?

推荐答案

当前语义来自

@JvmField和对象

我们已经使生成纯字段(与get/set对相对)的策略更加可预测:从现在开始,只有标注为@JvmFieldlateinitconst的属性才作为字段公开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生成静态吸气剂,而不是作为Foo.getC_ID()可以访问的Foo实例吸气剂.

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天全站免登陆