次のコードをKotlinに変換しようとしていますが、Javaで使用されるクラス(Foo)の1つがまだあります。この変換を行う適切な方法は何ですか?
元の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)
}
問題:
バークラスはC_IDまたはVALUESにアクセスできなくなりました(エラー:「プライベートアクセス」)
c_IDの前に「const」を置くと、機能しますが、VALUESで同じことはできません(「const」はプリミティブまたは文字列でのみ使用できます)
私がこれを行うべき別の方法はありますか(だからJavaコードとKotlinコードはFooのすべてにアクセスできます)?
現在のセマンティクスは、 Kotlin Beta Candidate :
@JvmFieldとオブジェクト
純粋なフィールド(
get
/set
ペアではなく)を生成する戦略をより予測可能にしました。これからは、_@JvmField
_、lateinit
またはconst
は、Javaクライアントにフィールドとして公開されます。古いバージョンは、ヒューリスティックを使用し、オブジェクトに静的フィールドを無条件に作成しました。また、シングルトンインスタンスは、_
INSTANCE$
_ではなく、INSTANCE
という名前でアクセスできるようになりました。
これと 参照 によると、JavaのKotlin object
のプロパティを操作する方法は3つあります。
_Foo.INSTANCE
_を使用します。
デフォルトでは、object
のプロパティはJavaの静的フィールドではありませんが、JavaはFoo
オブジェクトインスタンス-_Foo.INSTANCE
_を介してプロパティにアクセスできます。
したがって、式はFoo.INSTANCE.getC_ID()
になります。
_@JvmStatic
_アノテーションでプロパティをマークします:
_object Foo {
@JvmStatic val C_ID = "ID"
//...
}
_
これにより、Foo.getC_ID()
としてアクセス可能なFoo
インスタンスゲッターの代わりに、_C_ID
_の静的ゲッターが生成されます。
プロパティ宣言で_@JvmField
_注釈を使用します。
_object Foo {
@JvmField val C_ID = "ID"
//...
}
_
これにより、Kotlinコンパイラは、プロパティの代わりにJavaの静的フィールドを生成します。その後、Javaで静的フィールドとしてアクセスできます:_Foo.C_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)
}
}
}
その後、Foo.getAll()、Foo.C_ID、Foo.C_NAME、Foo.VALUESを呼び出すことができます。
「kotlin way」の値にアクセスできるはずです。
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)
}
fun main(args: Array<String>) {
Foo.all.forEach { it->println(it) }
}
結果として:
ID
NAME
Process finished with exit code 0
定数のためだけに新しい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)
}
あなたのメインアクティビティでは、定数名で定数にアクセスできますAndroid studioは自動的に定数をインポートします。ここに私のmainActivityがあります:
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)
}
}
}
ログ出力を正常に取得できました