Son zamanlarda public static final
Javaspeak’te küresel sabitleri veya alanları depolamak için en iyi yaklaşım hakkında çevrimiçi bir tartışma yapıldı. Bu kısa makalede, mevcut seçenekler açıklanmakta ve karşılaşabileceğiniz bazı tehlikelere dikkat çekilmektedir. Ama başlamadan önce, biraz Kotlin kodunu çözmekten bahsedelim.
Açma Kotlin
Kotlin’i bir süre kullandıysanız, dilin harika bir kazan plakası azaltma aracı olduğunu fark etmeliydiniz. Kotlin, karmaşık işleri basit kodla ifade etmeyi kolaylaştırır, derleyici kirli işi yapar. Harika bir örnekdata class
Bu özellik, onlarca satır Java kodunu yalnızca tek bir Kotlin satırıyla kolayca değiştirmenize olanak sağlayan özelliktir. Ancak, hepimizin bildiği gibi, büyük bir güçle büyük sorumluluk gelir. Kotlin derleyicisinin en düşük byte kodu üretmesini sağlamak zor değildir ve özellikle Android için Kotlin kullanıyorsanız, kodunuzun üreteceği sınıfların, yöntemlerin ve nesne tahsislerinin sayısının farkında olmalısınız. Neyse ki, JetBrains bize Android Studio’ya (ve elbette IntelliJ IDEA) entegre edilmiş bir kod çözücü aracıyla kaplı, bu da bytecode’u incelemeye yardımcı oluyor ve hatta benzer Java kodu üretiyor. Sonuncusu Kotlin’i optimize etmeyi kolaylaştırıyor.
Kotlin’in ayrıştırılması konusunda çevrimiçi olarak çok sayıda harika kaynak var, bu yüzden burada fazla ayrıntıya girmeyeceğim ve sadece bazı bağlantıları paylaşacağım:
- Piotr Ślesarew tarafından ” Kotlin’de sıfır kazan delegasyonu” , decompiler aracının nasıl kullanılacağı hakkında ayrıntılı bir açıklama sağlar.
- “Kotlin: ele geçen”, hem Droidcon Boston konuşma ve yazı dizisi ile Victoria Gonda , decompiling KOTLIN hakkında ayrıntılı gider
- Christophe B.’nin “Kotlin’in gizli maliyetlerini keşfetme” serisi , Kotlin ile çalışırken dikkat edilmesi gereken şeylerin harika bir derlemesidir.
Şimdi ana konuya doğrudan geçelim: sabitler.
Kotlin Sabitleri
Tamamlayıcı nesneler
static
Kotlin’de anahtar kelime yok . Sınıfınızın belirli alanlarına veya yöntemlerine statik erişim istiyorsanız, bunları a altına koymanız gerekir companion object
. Bir sabit ilan etmenin saf bir yolu şöyle görünür:
class Constants {
companion object {
val FOO = "foo"
}
}
Bu alan global olarak erişilebilir ve aracılığıyla erişilebilir olacaktır Constants.FOO
. Fakat şimdi kod çözücüyü kullanalım ve Java ile yazılmışsa bu kodun nasıl görüneceğini görelim (basitleştirilmiş değişken):
public final class Constants {
@NotNull
private static final String FOO = "foo";
public static final Constants.Companion Companion = new Constants.Companion((DefaultConstructorMarker)null);
public static final class Companion {
@NotNull
public final String getFOO() {
return Constants.FOO;
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
Burada, eşlik eden bir nesnenin gerçek bir nesne olduğunu not etmek önemlidir: Kotlin’in Constants.FOO
çağrısı Java’ya çevrilecektir Constants.Companion.getFOO()
. Bu sürüm oldukça kötü, çünkü bir nesneyi ve kaçınılması gereken bir yöntemi tanıtıyor.
Constants
Bizim örnek geliştirmek için basit bir yolu işaretlemek için olduğu FOO
kadar const
:
class Constants {
companion object {
const val FOO = "foo"
}
}
İşte Java versiyonu:
public final class Constants {
@NotNull
public static final String FOO = "foo";
public static final Constants.Companion Companion = new Constants.Companion((DefaultConstructorMarker)null);
public static final class Companion {
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
Alıcı gitti ve şimdi sahaya doğrudan statik erişimimiz var, fakat yine de derleyici tarafından üretilen işe yaramaz bir eşlikçi nesnesine sahibiz. Unutulmaması gereken bir başka şey, const
sadece ilkel ve dizeleri ile çalışır:
class Constants {
companion object {
// won't compile
const val FOO = Foo()
}
}
Bir geçici çözüm @JvmField
şuna ek açıklama kullanmaktır val
:
class Constants {
companion object {
@JvmField val FOO = Foo()
}
}
Bu Foo
örneği yapacak public static final
. Davranışı const
ve davranışları arasında önemli bir fark var @JvmField
: const val
derleyici tarafından belirtilen bir kazanca erişir , ancak @JvmField
yok. Aşağıdaki kodu alalım:
fun main(args: Array<String>) {
println(Constants.FOO)
}
İşte ne alıyoruz @JvmField val FOO = Foo()
:
public final class MainKt {
public static final void main(@NotNull String[] args) {
Intrinsics.checkParameterIsNotNull(args, "args");
Foo var1 = Constants.FOO;
System.out.println(var1);
}
}
ve ile const val FOO = "foo"
:
public final class MainKt {
public static final void main(@NotNull String[] args) {
Intrinsics.checkParameterIsNotNull(args, "args");
String var1 = "foo";
System.out.println(var1);
}
}
Constants.FOO
İkinci örnekte çağrı yok , değer satır içi.
Sınıfı ve nesneyi bırakmak
Tek ihtiyacımız olan bir sabit setse – hem sınıfı hem de nesneyi güvenle bırakıp üst düzey val
s’yi kullanabiliriz:
const val FOO = "foo"
Sonuç, tam olarak Java ile yazdığınız şekildedir:
public final class ConstantsKt {
@NotNull
public static final String FOO = "foo";
}
Kotlin’de, değerine global olarak ismiyle erişiyor olacaksınız. Değeri Java kodunda kullanıyorsanız arayacaksınız ConstantsKt.FOO
. Kt
Sınıf adlarında soneklerden kaçınmak için , file:@JvmName
daha okunabilir bir ad belirlemek için dosyanın üstündeki notu kullanın :
@file:JvmName("Constants")
Derleyici, sınıf adı için sağlanan değeri kullanacaktır:
public final class Constants {
@NotNull
public static final String FOO = "foo";
}
Sonuç
static
Kotlin’de hiç anahtar kelime olmamasına rağmen , küresel olarak erişilebilir sabitleri tanımlamak kolaydır. Bunu yanlış anlamak ve gereksiz yöntemleri ve nesne tahsisatlarını bytecode’a eklemek oldukça kolaydır. Kod çözücü aracı, bu tür sorunları bulmanıza ve çözmenize yardımcı olabilir ve ek bir fayda sağlar – Kotlin’in büyüsünün kaputun altında nasıl çalıştığını çabucak öğreneceksiniz! İyi eğlenceler!
GIPHY App Key not set. Please check settings