2017/03/25 このエントリーをはてなブックマークに追加 はてなブックマーク - Kotlinにstaticが無いのなんで?(Why doesn't Kotlin have static members inside a class?)

Kotlinにstaticが無いのなんで?(Why doesn't Kotlin have static members inside a class?)



って前に聞かれたけど、スッと答えられなかったのでここに記します。


※このあたり(https://speakerdeck.com/ntaro/kotlinwoshi-meyouhanzuon-number-droidkaigi-number-droidkaigi6?slide=41







「objectかcompanion objectを使いましょう」が、対応としては合ってます。


   companion object {
        @JvmField
        val CREATOR: Parcelable.Creator<Repository> = object : Parcelable.Creator<Repository> {
            override fun createFromParcel(source: Parcel): Repository =
                    Repository(source.readLong(),
                            source.readString(),
                            source.readString(),
                            source.readString(),
                            source.readInt(),
                            source.readParcelable(Repository::class.java.classLoader),
                            source.readString())

            override fun newArray(size: Int): Array<out Repository?> = kotlin.arrayOfNulls(size)
        }
    }

staticなCREATORというフィールドが必要な場合は、companion objectを利用して、JvmFieldアノテーションでコンパイラーへの目印とすればコード生成時にclassに属するstaticフィールドと言うかたちでクラスバイトコードを作ってくれるって感じです。



言語デザイン的にstaticというのは要らんやろというのが理由です。


以下のKotlinのブログに言及があります。
https://blog.jetbrains.com/kotlin/2013/06/static-constants-in-kotlin/


Kotlin is designed so that there’s no such thing as a “static member” in a class. 
If you have a function in a class, it can only be called on instances of this class. 
If you need something that is not attached to an instance of any class, 
you define it in a package, 
outside any class (we call it package-level functions):

Kotlinはクラスにstatic memberを持たず、任意のクラスのinstanceに対しての関数呼び出しだけになるだろうということです。クラスに属する関数でない場合はパッケージに属する関数呼び出しになる、と。そのいずれかになるのでstaticは要らんだろうということみたいです。


この頃(マイルストーン5.3。メジャーバージョン前の2013年)はJvmFieldアノテーションとかなくて、staticフィールドをクラスバイトコードになった状態で提供する方法が無かった。あと、objectを利用する例が載っていますが、現在ではcompanion objectを利用するようになっています。マイルストーン11での変更です。コレもメジャーバージョン前です。


https://blog.jetbrains.com/kotlin/2015/03/kotlin-m11-is-out/


なんか当時書いてたやつ。↓
【Kotlin】M11(マイルストーン11)の目玉、Companion Objectとlamdaと関数オブジェクト




いやいや、よう分からん。なんで要らんねん。ということもあるでしょう。
という場合はここらへんに書いてることを読むといいかもしれません。Scalaですけど、言ってる内容は同じなので。
http://stackoverflow.com/questions/7302206/why-doesnt-scala-have-static-members-inside-a-class


オブジェクト指向的にstaticとかよろしくないやろみたいなやつです。オブジェクトに属さない存在とはなんだということですかね。


こんなんが出来るのがうわぁ、て感じって話かなと思います。

public static void main(String[] args) { 
        String str = ((String) (null)).valueOf(123); 
        BigDecimal ten = ((BigDecimal) (null)).TEN;
        System.out.println(str); 
        System.out.println(ten);
}

なんかOOPとは、、とか考え出すと原理主義的になるので雰囲気で良いと思うんですけどね、個人的には。我々は雰囲気でコードを書いている。



companion objectとobjectはシングルトンパターンのクラスと思ってもらえれば大体オッケーです。companion objectは制約付きのobjectみたいな感じです。


気になる方はcomapnion objectやobjectを書いてみてIntelliJ IDEAかAndroid Studioで出来たクラスバイトコードをデコンパイルして見て下さい。


参考:
「Show Kotlin Bytecode」でKotlinを理解する



  • Kotlinにはstaticフィールドはない。
  • staticフィールドはなくてシングルトンなんだけどstaticフィールドのようなアクセスが出来る
  • そういう風にしてるのは言語デザイン的にstatic要らんやろってなってるから
  • でもバイトコード上でstaticフィールド求められるときはあるからJvmFieldというものを提供している

















0 件のコメント:

コメントを投稿