2016/12/14の30分 Kotlinメモ🎁

2016/12/14の30分 Kotlinメモ🎁

書いてるコードは雑にここにあります。

github.com

引き続き Calling Java code from Kotlin読んでる

kotlinlang.org

@ReadOnly@MutableJavaのCollectionをKotlin TypeのCollectionにする

昨日の夕方以下のようなことが気になってた...

JavaのCollectionは(Mutable)Collection!型になると。。。

Listなら(Mutable)List!ね。

ということは、以下のコードみたいにJavaで不変なListを作った場合に、Kotlinから見ると(Mutable)List!になるから、変更できるように見れるかー。 JavaからKotlinへ不変なListであることは伝えられない??

んで、夜に第4回 Kotlin Sansan勉強会に行くと、その答えをまさに教えてくださる救世主現る!

@RyotaMurohoshiさんが昨日その勉強会で発表した資料に答えが書いてあった。



要はCollectionを返すメソッドなりに@ReadOnly or @Mutableを付ければOKだよ!って話。

例えば昨日書いた不変なListと可変なListなら以下のように書けばいいと。

import org.jetbrains.annotations.Mutable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class JavaJava {

    @ReadOnly
    public List<String> getImmutableList() {
        return Collections.unmodifiableList(new ArrayList<>());
    }

    @Mutable
    public List<String> getMutableList() {
        return new ArrayList<>();
    }
}

// Kotlin
fun run() {
    val java = JavaJava()

    java.immutableList // List<String!>

    val l = java.mutableList // MutableList<String!>
    l.add("test")
    println(l) // [ test ]
}

うん、@ReadOnlyをつけたListのTypeはList<String!>になり、@MutableをつけたListのTypeはMutableList<String!>になってると。

うむ、うむ、うむ、よい☺

というか対応してるannotationsのKotlin compiler source code見たらちゃんと書いてあった。

github.com

val READ_ONLY_ANNOTATIONS = listOf(
        JvmAnnotationNames.JETBRAINS_READONLY_ANNOTATION
)

val MUTABLE_ANNOTATIONS = listOf(
        JvmAnnotationNames.JETBRAINS_MUTABLE_ANNOTATION
)

Calling Kotlin from Java

kotlinlang.org

はい、じゃ次はKotlinのコードをJavaで見るとどうなるのって話を見てみる。

Package-Level Functions

クラスとTop Levelの関数がどう見えるのかって話かな。

package test

class Sample {
}

fun test() {
}

// Java
public class CallingKotlinFromJavaSample {

    public static void run() {
        Sample sample = new Sample();
        SampleKt.test();
    }
}

Javaから参照する時の名前を指定できるらしい。マジかよ

@file:JvmName("SaSasSa") // Javaからみた場合にどういうクラス名にするかを決められる

package test

class Sample {
}

fun test() {
}


// Java
import test.SaSasSa;
import test.Sample;

public class CallingKotlinFromJavaSample {

    public static void run() {
        Sample sample = new Sample();
        SaSasSa.test();
    }
}

Instance Fields

KotlinのpropertyをJavaのInstance Fieldsととして見えるようにする方法かなー?

@file:JvmName("SaSasSa")

package test

class Sample {
    @JvmField val id = 0 // propertyをJavaのInstance Fieldsととして見えるようにする
}

fun test() {
}


// Java
import test.SaSasSa;
import test.Sample;

public class CallingKotlinFromJavaSample {

    public static void run() {
        Sample sample = new Sample();
        System.out.println(sample.id);
    }
}

まとめ

Kotlinの知見もっとほしいぞー🎁