Properties 将静态变量从Java转换为Kotlin
我试图将下面的代码转换为Kotlin,但仍然有Java使用的一个类(Foo)。进行这种转换的正确方式是什么 原始Java: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
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)
}
}
}