Properties 将静态变量从Java转换为Kotlin

Properties 将静态变量从Java转换为Kotlin,properties,static,field,kotlin,Properties,Static,Field,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 Str

我试图将下面的代码转换为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)
}
objectfoo{
val C_ID=“ID”
val C_NAME=“NAME”
val值=数组(“X”、“Y”、“Z”)
val all:数组
get()=arrayOf(C_ID,C_NAME)
}
问题:

Bar类无法再访问C_ID或值(错误:“私有访问”)

如果我把“const”放在C_ID前面,它会工作。。。但我不能对值做同样的处理(“const”只能用于primative或String)


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

您应该能够访问值“Kotlin方法”:


当前语义来自:

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

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

根据这一点和,有三种方法可以处理来自Java的Kotlin
对象的属性:

  • 使用
    Foo.INSTANCE

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

    因此表达式将是
    Foo.INSTANCE.getC_ID()

  • 使用
    @JvmStatic
    注释标记属性:

    object Foo {
        @JvmStatic val C_ID = "ID"
        //...
    }
    
    这将为
    C\u ID
    生成静态getter,而不是
    Foo
    实例getter,实例getter将作为
    Foo.getC\u ID()
    访问

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

    object Foo {
        @JvmField val C_ID = "ID"
        //...
    }
    
    这将使Kotlin编译器为Java生成一个静态字段,而不是属性。 然后在Java中,您可以作为静态字段访问它:
    Foo.C\u ID

    但是,在您的示例中,如果没有像
    all
    这样的支持字段,它将无法处理属性

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


顺便说一句,当谈到方法时,情况是一样的,它们有
@JvmStatic
注释。

在您的foo类中,您可以将这些属性和方法放在一个伴随对象中:

class Foo {

  companion object {
     val C_ID:String = "ID"
     val C_NAME:String = "NAME"
     @JvmField val VALUES = arrayOf("X", "Y", "Z")

     fun getAll():Array<String> {
        return arrayOf(C_ID, C_NAME)
     }
  }
}
class-Foo{
伴星{
val C_ID:String=“ID”
val C_NAME:String=“NAME”
@JvmField val VALUES=arrayOf(“X”、“Y”、“Z”)
fun getAll():数组{
返回数组(C_ID,C_名称)
}
}
}

然后可以调用Foo.getAll()、Foo.C_ID、Foo.C_NAME和Foo.VALUES。

最好只为常量创建新的kotlin文件

创建Constants.kt文件并粘贴到下面的代码中

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

val all: Array<String>
    get() = arrayOf(C_ID, C_NAME)
}
我能够成功地获得日志输出


问题是如何访问Java中Kotlin
对象的部分,您所说的“Kotlin方式”是什么意思?为什么要通过数组访问
C_ID
C_NAME
?op有一个val“all”,其中包含一个数组作为getter。我决定在我的示例代码中使用它。我不是kotlin的专家,但我会这样做的,抱歉,我没有注意到
all
val。虽然问题似乎更多地是关于Java互操作的。虽然
const val
可能有您需要的效果,但它的用途不同(编译器时间常数),不应该将其用于互操作。
class Foo {

  companion object {
     val C_ID:String = "ID"
     val C_NAME:String = "NAME"
     @JvmField val VALUES = arrayOf("X", "Y", "Z")

     fun getAll():Array<String> {
        return arrayOf(C_ID, C_NAME)
     }
  }
}
object Constants {
val C_ID = "ID"
val C_NAME = "NAME"
val VALUES = arrayOf("X", "Y", "Z")

val all: Array<String>
    get() = arrayOf(C_ID, C_NAME)
}
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.example.architecturecompintro.Constants.C_ID
import com.example.architecturecompintro.Constants.C_NAME
import com.example.architecturecompintro.Constants.VALUES
import com.example.architecturecompintro.Constants.all

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val TAG = "info"

        Log.i(TAG, C_ID)
        Log.i(TAG,C_NAME)

        for(item in VALUES) {
            Log.i(TAG,item)
        }
        val arrayItem = all

        for(item in arrayItem) {
            Log.i(TAG,item)
        }
    }
}