Tidak ada static
kata kunci di Kotlin.
Apa cara terbaik untuk mewakili static
metode Java di Kotlin?
Tidak ada static
kata kunci di Kotlin.
Apa cara terbaik untuk mewakili static
metode Java di Kotlin?
Jawaban:
Anda menempatkan fungsi di "objek pengiring".
Jadi kode java seperti ini:
class Foo {
public static int a() { return 1; }
}
akan menjadi
class Foo {
companion object {
fun a() : Int = 1
}
}
Anda kemudian dapat menggunakannya dari dalam kode Kotlin sebagai
Foo.a();
Tetapi dari dalam kode Java, Anda harus menyebutnya sebagai
Foo.Companion.a();
(Yang juga bekerja dari dalam Kotlin.)
Jika Anda tidak suka harus menentukan Companion
bit, Anda bisa menambahkan @JvmStatic
anotasi atau memberi nama kelas rekan Anda.
Dari dokumen :
Objek Pendamping
Deklarasi objek di dalam kelas dapat ditandai dengan kata kunci pengiring:
class MyClass { companion object Factory { fun create(): MyClass = MyClass() } }
Anggota objek pendamping dapat dipanggil dengan hanya menggunakan nama kelas sebagai kualifikasi:
val instance = MyClass.create()
...
Namun, pada JVM Anda dapat memiliki anggota objek pendamping yang dihasilkan sebagai metode dan bidang statis nyata, jika Anda menggunakan
@JvmStatic
anotasi. Lihat bagian interoperabilitas Java untuk lebih jelasnya.
Menambahkan @JvmStatic
anotasi terlihat seperti ini
class Foo {
companion object {
@JvmStatic
fun a() : Int = 1;
}
}
dan kemudian akan ada sebagai fungsi statis Java nyata, dapat diakses dari Java dan Kotlin sebagai Foo.a()
.
Jika itu hanya tidak disukai untuk Companion
nama, maka Anda juga dapat memberikan nama eksplisit untuk objek pendamping terlihat seperti ini:
class Foo {
companion object Blah {
fun a() : Int = 1;
}
}
yang akan membiarkan Anda memanggilnya dari Kotlin dengan cara yang sama, tetapi dari java like Foo.Blah.a()
(yang juga akan bekerja di Kotlin).
fun a(): Int { return 1 }
atau bahkanfun a(): Int = 1
fun a() = 1
.
Factory
adalah nama objek pendamping - tapi untuk apa itu bisa digunakan? Saya tidak tahu, tapi saya tertarik jadi saya membuat pertanyaan yang didedikasikan untuk itu: stackoverflow.com/q/45853459/221955 .
Docs merekomendasikan untuk menyelesaikan sebagian besar kebutuhan untuk fungsi statis dengan fungsi tingkat paket . Mereka hanya dideklarasikan di luar kelas dalam file kode sumber. Paket file dapat ditentukan di awal file dengan kata kunci paket.
Pernyataan
package foo
fun bar() = {}
Pemakaian
import foo.bar
kalau tidak
import foo.*
Anda sekarang dapat memanggil fungsi dengan:
bar()
atau jika Anda tidak menggunakan kata kunci impor:
foo.bar()
Jika Anda tidak menentukan paketnya, fungsinya akan dapat diakses dari root.
Jika Anda hanya memiliki pengalaman dengan java, ini mungkin tampak sedikit aneh. Alasannya adalah bahwa kotlin bukan bahasa berorientasi objek yang ketat. Bisa dibilang ini mendukung metode di luar kelas.
Sunting: Mereka telah mengedit dokumentasi untuk tidak lagi menyertakan kalimat tentang merekomendasikan fungsi tingkat paket. Ini asli yang disebut di atas.
class FooPackage
dengan semua properti dan fungsi tingkat atas, dan merutekan semua referensi Anda ke mereka dengan tepat. Info lebih lanjut dari jetbrains.
bar()
tidak masalah nama file, Anda dapat menamainya BarUtils.kt
atau apa pun, maka seperti yang dikatakan teks Anda akan mengimpornya denganimport <package name>.bar
A. Cara Jawa Kuno:
Nyatakan a companion object
untuk menyertakan metode / variabel statis
class Foo{
companion object {
fun foo() = println("Foo")
val bar ="bar"
}
}
Gunakan:
Foo.foo() // Outputs Foo
println(Foo.bar) // Outputs bar
B. Cara Kotlin baru
Deklarasikan langsung pada file tanpa kelas pada .kt
file.
fun foo() = println("Foo")
val bar ="bar"
Gunakan methods/variables
dengan nama mereka . ( Setelah mengimpor mereka )
Gunakan:
foo() // Outputs Foo
println(bar) // Outputs bar
INSTANCE
kata kunci, seperti ini:Foo.INSTANCE.sayFoo()
static CLASS
tidak adil static methdos
. Karena dengan objek pendamping Anda masih dapat membuat instance kelas induk.
val
tidak statis sama dengan static final
di Jawa
Gunakan objek untuk mewakili val / var / metode untuk membuat statis. Anda dapat menggunakan objek bukan kelas tunggal juga. Anda dapat menggunakan pendamping jika Anda ingin membuat statis di dalam kelas
object Abc{
fun sum(a: Int, b: Int): Int = a + b
}
Jika Anda perlu memanggilnya dari Jawa:
int z = Abc.INSTANCE.sum(x,y);
Di Kotlin, abaikan INSTAN.
object objectName {
fun funName() {
}
}
Anda harus melewati objek pengiring untuk metode statis karena kotlin tidak memiliki kata kunci statis - Anggota objek pengiring dapat dipanggil dengan hanya menggunakan nama kelas sebagai kualifikasi:
package xxx
class ClassName {
companion object {
fun helloWord(str: String): String {
return stringValue
}
}
}
Ada 2 cara Anda dapat menerapkan statis di Kotlin
Pertama buat objek pendamping di bawah kelas
Misalnya:
class Test{
companion object{
fun isCheck(a:Int):Boolean{
if(a==0) true else false
}
}
}
Anda dapat memanggil fungsi ini sebagai
Test.Companion.isCheck(2)
Cara lain yang bisa kita gunakan adalah membuat kelas objek
object Test{
fun isCheck(a:Int):Boolean{
if(a==0) true else false
}
}
Selamat Coding!
Test.Companion.isCheck(2)
) IDE menampilkan peringatan dan ucapkan Companion reference is redundant
. Itu bisa dikurangi menjadi Test.isCheck(2)
dan bentuk dikurangi lebih dekat dengan setara java.
Kotlin tidak memiliki kata kunci statis. Anda menggunakannya untuk java
class AppHelper {
public static int getAge() {
return 30;
}
}
dan Untuk Kotlin
class AppHelper {
companion object {
fun getAge() : Int = 30
}
}
Panggilan untuk Jawa
AppHelper.getAge();
Panggil Kotlin
AppHelper.Companion.getAge();
Saya pikir ini bekerja dengan sempurna.
Saya ingin menambahkan sesuatu ke jawaban di atas.
Ya, Anda dapat mendefinisikan fungsi dalam file kode sumber (di luar kelas). Tetapi lebih baik jika Anda mendefinisikan fungsi statis di dalam kelas menggunakan Objek Pengiring karena Anda dapat menambahkan lebih banyak fungsi statis dengan memanfaatkan Ekstensi Kotlin .
class MyClass {
companion object {
//define static functions here
}
}
//Adding new static function
fun MyClass.Companion.newStaticFunction() {
// ...
}
Dan Anda dapat memanggil fungsi yang didefinisikan di atas karena Anda akan memanggil fungsi apa pun di dalam Objek Pengiring.
Meskipun ini sedikit lebih dari 2 tahun sekarang, dan punya banyak jawaban bagus, saya melihat beberapa cara lain untuk mendapatkan bidang "statis" Kotlin hilang. Berikut adalah contoh panduan untuk static
interop Kotlin-Java :
Skenario 1: Membuat metode statis di Kotlin untuk Java
Kotlin
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits class KotlinClass { companion object { //This annotation tells Java classes to treat this method as if it was a static to [KotlinClass] @JvmStatic fun foo(): Int = 1 //Without it, you would have to use [KotlinClass.Companion.bar()] to use this method. fun bar(): Int = 2 } }
Jawa
package com.frybits; class JavaClass { void someFunction() { println(KotlinClass.foo()); //Prints "1" println(KotlinClass.Companion.bar()); //Prints "2". This is the only way to use [bar()] in Java. println(KotlinClass.Companion.foo()); //To show that [Companion] is still the holder of the function [foo()] } //Because I'm way to lazy to keep typing [System.out], but I still want this to be compilable. void println(Object o) { System.out.println(o); } }
Jawaban Michael Anderson memberikan kedalaman lebih dari ini, dan pasti harus dijadikan referensi untuk skenario ini.
Skenario berikut ini menangani pembuatan bidang statis di Kotlin sehingga Java tidak harus terus memanggil KotlinClass.foo()
kasus-kasus di mana Anda tidak ingin fungsi statis.
Skenario 2: Membuat variabel statis di Kotlin untuk Java
Kotlin
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits class KotlinClass { companion object { //This annotation tells Kotlin to not generate the getter/setter functions in Java. Instead, this variable should be accessed directly //Also, this is similar to [@JvmStatic], in which it tells Java to treat this as a static variable to [KotlinClass]. @JvmField var foo: Int = 1 //If you want something akin to [final static], and the value is a primitive or a String, you can use the keyword [const] instead //No annotation is needed to make this a field of [KotlinClass]. If the declaration is a non-primitive/non-String, use @JvmField instead const val dog: Int = 1 //This will be treated as a member of the [Companion] object only. It generates the getter/setters for it. var bar: Int = 2 //We can still use [@JvmStatic] for 'var' variables, but it generates getter/setters as functions of KotlinClass //If we use 'val' instead, it only generates a getter function @JvmStatic var cat: Int = 9 } }
Jawa
package com.frybits; class JavaClass { void someFunction() { //Example using @JvmField println(KotlinClass.foo); //Prints "1" KotlinClass.foo = 3; //Example using 'const val' println(KotlinClass.dog); //Prints "1". Notice the lack of a getter function //Example of not using either @JvmField, @JvmStatic, or 'const val' println(KotlinClass.Companion.getBar()); //Prints "2" KotlinClass.Companion.setBar(3); //The setter for [bar] //Example of using @JvmStatic instead of @JvmField println(KotlinClass.getCat()); KotlinClass.setCat(0); } void println(Object o) { System.out.println(o); } }
Salah satu fitur hebat tentang Kotlin adalah Anda dapat membuat fungsi dan variabel tingkat atas. Ini membuatnya greate untuk membuat daftar "classless" dari bidang dan fungsi konstan, yang pada gilirannya dapat digunakan sebagai static
fungsi / bidang di Jawa.
Skenario 3: Mengakses bidang dan fungsi tingkat atas di Kotlin dari Jawa
Kotlin
//In this example, the file name is "KSample.kt". If this annotation wasn't provided, all functions and fields would have to accessed //using the name [KSampleKt.foo()] to utilize them in Java. Make life easier for yourself, and name this something more simple @file:JvmName("KotlinUtils") package com.frybits //This can be called from Java as [KotlinUtils.TAG]. This is a final static variable const val TAG = "You're it!" //Since this is a top level variable and not part of a companion object, there's no need to annotate this as "static" to access in Java. //However, this can only be utilized using getter/setter functions var foo = 1 //This lets us use direct access now @JvmField var bar = 2 //Since this is calculated at runtime, it can't be a constant, but it is still a final static variable. Can't use "const" here. val GENERATED_VAL:Long = "123".toLong() //Again, no need for @JvmStatic, since this is not part of a companion object fun doSomethingAwesome() { println("Everything is awesome!") }
Jawa
package com.frybits; class JavaClass { void someFunction() { println(KotlinUtils.TAG); //Example of printing [TAG] //Example of not using @JvmField. println(KotlinUtils.getFoo()); //Prints "1" KotlinUtils.setFoo(3); //Example using @JvmField println(KotlinUtils.bar); //Prints "2". Notice the lack of a getter function KotlinUtils.bar = 3; //Since this is a top level variable, no need for annotations to use this //But it looks awkward without the @JvmField println(KotlinUtils.getGENERATED_VAL()); //This is how accessing a top level function looks like KotlinUtils.doSomethingAwesome(); } void println(Object o) { System.out.println(o); } }
Disebutkan lain yang dapat digunakan di Jawa sebagai bidang "statis" adalah object
kelas Kotlin . Ini adalah nol parameter kelas tunggal yang dipakai malas saat digunakan pertama kali. Informasi lebih lanjut tentang mereka dapat ditemukan di sini: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations
Namun, untuk mengakses singleton, sebuah INSTANCE
objek khusus dibuat, yang sama rumitnya untuk ditangani sebagaimana Companion
adanya. Berikut cara menggunakan anotasi untuk memberikan kesan bersih static
di Jawa:
Skenario 4: Menggunakan
object
kelasKotlin
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits object KotlinClass { //No need for the 'class' keyword here. //Direct access to this variable const val foo: Int = 1 //Tells Java this can be accessed directly from [KotlinClass] @JvmStatic var cat: Int = 9 //Just a function that returns the class name @JvmStatic fun getCustomClassName(): String = this::class.java.simpleName + "boo!" //Getter/Setter access to this variable, but isn't accessible directly from [KotlinClass] var bar: Int = 2 fun someOtherFunction() = "What is 'INSTANCE'?" }
Jawa
package com.frybits; class JavaClass { void someFunction() { println(KotlinClass.foo); //Direct read of [foo] in [KotlinClass] singleton println(KotlinClass.getCat()); //Getter of [cat] KotlinClass.setCat(0); //Setter of [cat] println(KotlinClass.getCustomClassName()); //Example of using a function of this 'object' class println(KotlinClass.INSTANCE.getBar()); //This is what the singleton would look like without using annotations KotlinClass.INSTANCE.setBar(23); println(KotlinClass.INSTANCE.someOtherFunction()); //Accessing a function in the object class without using annotations } void println(Object o) { System.out.println(o); } }
Untuk membuatnya singkat, Anda bisa menggunakan "objek pengiring" untuk masuk ke dunia statis Kotlin seperti:
companion object {
const val TAG = "tHomeFragment"
fun newInstance() = HomeFragment()
}
dan untuk membuat bidang konstan gunakan "const val" seperti dalam kode. tetapi cobalah untuk menghindari kelas statis karena membuat kesulitan dalam pengujian unit menggunakan Mockito !.
Konversi yang tepat dari metode java statis untuk setara kotlin akan seperti ini. mis. Di sini kelas util memiliki satu metode statis yang akan setara di kedua java dan kotlin. Penggunaan @JvmStatic penting.
Kode Java:
class Util{
public static String capitalize(String text){
return text.toUpperCase();}
}
Kode Kotlin:
class Util {
companion object {
@JvmStatic
fun capitalize(text:String): String {
return text.toUpperCase()
}
}
}
Cukup Anda perlu membuat objek pendamping dan memasukkan fungsi di dalamnya
class UtilClass {
companion object {
// @JvmStatic
fun repeatIt5Times(str: String): String = str.repeat(5)
}
}
Untuk memanggil metode dari kelas kotlin:
class KotlinClass{
fun main(args : Array<String>) {
UtilClass.repeatIt5Times("Hello")
}
}
atau Menggunakan impor
import Packagename.UtilClass.Companion.repeatIt5Times
class KotlinClass{
fun main(args : Array<String>) {
repeatIt5Times("Hello")
}
}
Untuk memanggil metode dari kelas java:
class JavaClass{
public static void main(String [] args){
UtilClass.Companion.repeatIt5Times("Hello");
}
}
atau dengan menambahkan penjelasan @JvmStatic ke metode
class JavaClass{
public static void main(String [] args){
UtilClass.repeatIt5Times("Hello")
}
}
atau keduanya dengan menambahkan penjelasan @JvmStatic ke metode dan membuat impor statis di java
import static Packagename.UtilClass.repeatIt5Times
class JavaClass{
public static void main(String [] args){
repeatIt5Times("Hello")
}
}
Untuk Jawa:
public class Constants {
public static final long MAX_CLICK_INTERVAL = 1000;}
Kode Kotlin Setara:
object Constants {
const val MAX_CLICK_INTERVAL: Long = 1000}
Jadi untuk ekivalen dari metode statis Java adalah kelas objek di Kotlin.
Untuk Android menggunakan string dari satu aktivitas ke semua aktivitas yang diperlukan. Sama seperti statis di java
public final static String TEA_NAME = "TEA_NAME";
Pendekatan Setara di Kotlin:
class MainActivity : AppCompatActivity() {
companion object {
const val TEA_NAME = "TEA_NAME"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Aktivitas lain di mana nilai dibutuhkan:
val teaName = MainActivity.TEA_NAME
kecuali jawaban Michael Anderson, saya memiliki kode dengan dua cara lain dalam proyek saya.
Anda dapat memutihkan semua variabel menjadi satu kelas. membuat file kotlin bernama Const
object Const {
const val FIRST_NAME_1 = "just"
const val LAST_NAME_1 = "YuMu"
}
Anda dapat menggunakannya dalam kode kotlin dan java
Log.d("stackoverflow", Const.FIRST_NAME_1)
Anda dapat menggunakan fungsi ekstensi Kotlin
membuat file kotlin bernama Ext, kode di bawah ini adalah semua kode dalam file Ext
package pro.just.yumu
/**
* Created by lpf on 2020-03-18.
*/
const val FIRST_NAME = "just"
const val LAST_NAME = "YuMu"
Anda dapat menggunakannya dalam kode kotlin
Log.d("stackoverflow", FIRST_NAME)
Anda dapat menggunakannya dalam kode java
Log.d("stackoverflow", ExtKt.FIRST_NAME);
Tuliskan langsung ke file.
Di Jawa (jelek):
package xxx;
class XxxUtils {
public static final Yyy xxx(Xxx xxx) { return xxx.xxx(); }
}
Di Kotlin:
@file:JvmName("XxxUtils")
package xxx
fun xxx(xxx: Xxx): Yyy = xxx.xxx()
Kedua potongan kode tersebut sama dengan setelah kompilasi (bahkan nama file yang dikompilasi, file:JvmName
digunakan untuk mengontrol nama file yang dikompilasi, yang harus diletakkan tepat sebelum deklarasi nama paket).
Gunakan @JVMStatic
Anotasi
companion object {
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
EditProfileFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
Biarkan, Anda memiliki Siswa kelas . Dan Anda memiliki satu metode statis getUniversityName () & satu bidang statis yang disebut totalStudent .
Anda harus mendeklarasikan blok objek pendamping di dalam kelas Anda.
companion object {
// define static method & field here.
}
Kemudian kelas Anda terlihat seperti
class Student(var name: String, var city: String, var rollNumber: Double = 0.0) {
// use companion object structure
companion object {
// below method will work as static method
fun getUniversityName(): String = "MBSTU"
// below field will work as static field
var totalStudent = 30
}
}
Kemudian Anda dapat menggunakan metode dan bidang statis seperti ini.
println("University : " + Student.getUniversityName() + ", Total Student: " + Student.totalStudent)
// Output:
// University : MBSTU, Total Student: 30
Tidak ada kata kunci statis di kotlin. kotlin docs merekomendasikan untuk menggunakan fungsi tingkat paket jika Anda ingin mengikuti KERING. Buat file dengan ekstensi .kt dan masukkan metode Anda di dalamnya.
package p
fun m(){
//fun body
}
setelah dikompilasi m akan memiliki tanda tangan public static final void
dan
import p.m
☺
Anda dapat mencapai fungsionalitas statis di Kotlin oleh Object Companion
Sebuah objek pendamping tidak dapat dideklarasikan di luar kelas.
class MyClass{
companion object {
val staticField = "This is an example of static field Object Decleration"
fun getStaticFunction(): String {
return "This is example of static function for Object Decleration"
}
}
}
Anggota objek pendamping dapat dipanggil dengan hanya menggunakan nama kelas sebagai kualifikasi:
Keluaran:
MyClass.staticField // This is an example of static field Object Decleration
MyClass.getStaticFunction() : // This is an example of static function for Object Decleration
Banyak orang menyebutkan benda pendamping, yang benar. Tapi, supaya Anda tahu, Anda juga dapat menggunakan segala jenis objek (menggunakan kata kunci objek, bukan kelas) yaitu,
object StringUtils {
fun toUpper(s: String) : String { ... }
}
Gunakan seperti metode statis apa pun di java:
StringUtils.toUpper("foobar")
Pola semacam itu agak tidak berguna di Kotlin, salah satu kelebihannya adalah ia menghilangkan kebutuhan akan kelas yang dipenuhi dengan metode statis. Lebih tepat menggunakan fungsi global, ekstensi, dan / atau sebagai gantinya, tergantung pada use case Anda. Di tempat saya bekerja, kita sering mendefinisikan fungsi ekstensi global dalam file flat dan terpisah dengan konvensi penamaan: [className] Extensions.kt yaitu, FooExtensions.kt. Tetapi lebih khusus kita menulis fungsi di mana mereka dibutuhkan di dalam kelas atau objek operasi mereka.
Di Jawa, kita bisa menulis dengan cara di bawah ini
class MyClass {
public static int myMethod() {
return 1;
}
}
Di Kotlin, kita bisa menulis dengan cara di bawah ini
class MyClass {
companion object {
fun myMethod() : Int = 1
}
}
seorang teman digunakan sebagai statis di Kotlin.
Penyedia dokumen kotlin tiga cara untuk melakukan itu, yang pertama adalah mendefinisikan fungsi dalam paket, tanpa kelas:
package com.example
fun f() = 1
yang kedua adalah menggunakan penjelasan @JvmStatic:
package com.example
class A{
@JvmStatic
fun f() = 1
}
dan yang ketiga adalah menggunakan objek pendamping:
package com.example
clss A{
companion object{
fun f() = 1
}
}
Jika Anda membutuhkan fungsi atau properti untuk diikat ke kelas daripada ke instance, Anda bisa mendeklarasikannya di dalam objek pendamping:
class Car(val horsepowers: Int) {
companion object Factory {
val cars = mutableListOf<Car>()
fun makeCar(horsepowers: Int): Car {
val car = Car(horsepowers)
cars.add(car)
return car
}
}
}
Objek pendamping adalah singleton, dan anggotanya dapat diakses langsung melalui nama kelas yang mengandung
val car = Car.makeCar(150)
println(Car.Factory.cars.size)
Kamu bisa menggunakan Objek Pendamping - kotlinlang
Yang dapat ditunjukkan dengan terlebih dahulu membuat Antarmuka itu
interface I<T> {
}
Maka kita harus membuat fungsi di dalam antarmuka itu:
fun SomeFunc(): T
Kemudian setelah itu, Kami membutuhkan kelas:
class SomeClass {}
di dalam kelas itu kita membutuhkan Object pendamping di dalam kelas itu:
companion object : I<SomeClass> {}
di dalam Object Companion itu kita membutuhkan SomeFunc
fungsi lama itu , Tapi kita harus naik itu:
override fun SomeFunc(): SomeClass = SomeClass()
Akhirnya di bawah semua pekerjaan itu, Kami membutuhkan sesuatu untuk mendukung fungsi statis itu, Kami membutuhkan variabel:
var e:I<SomeClass> = SomeClass()