2016-11-12 5 views
6

私はJava/Kotlin interopの問題があります。 Kotlin不変リストは、変更可能な通常のjava.util.ArrayListにコンパイルされます!Javaで不変なリストでもある不変のリストをKotlinで作成するには?

Kotlin(ライブラリ):

class A { 
    val items: List<Item> = ArrayList() 
} 

のJava(消費者):あまりにもJavaパースペクティブから、私のKotlinクラスは完全に不変にする方法

A a = new A(); 
a.getItems().add(new Item()); // Compiles and runs but I wish to fail or throw 

? Kotlinで

+0

私はKotlinに慣れていないんだけど、グアバJavaライブラリを使用すると、可変 'ArrayList'をラップするために使用することができます' ImmutableList'タイプがあります。これは、任意のコレクションで動作します。 – pathfinderelite

+1

unmodifiableList(ArrayList()) –

+1

動作します。答えとして投稿してください。 – WindRider

答えて

10

すべての非Mutable____コレクションはコンパイル時の読み取り専用タイプのデフォルトではなく、不変です。次のコードスニペットを参照してください:

fun main(args: Array<String>) { 
    // Explanation for ArrayList(listOf()) later down the post 
    val list: List<Int> = ArrayList(listOf(1, 2, 3)) 
    println(list) // [1, 2, 3] 

    // Fails at compile time 
    // list.add(4) 

    // Uh oh! This works at runtime! 
    (list as MutableList<Int>).add(4) 
    println(list) // [1, 2, 3, 4] 
} 

真に不変のリストを持っているために、グァバのImmutable____コレクションを考えてみます。

import com.google.common.collect.ImmutableList 

fun main(args: Array<String>) { 
    val list: List<Int> = ImmutableList.of(1, 2, 3) 
    println(list) // [1, 2, 3] 

    // Fails at compile time 
    // list.add(4) 

    // Fails at runtime, as expected 
    (list as MutableList<Int>).add(4) 
    println(list) // [1, 2, 3, 4] 
} 

は、Kotlinの標準ランタイム機能のいくつかがどちらかの変更不可能ですコレクションを返す可能性があることに注意しませうサイズ変更などが可能です。したがって、読み取り専用のコレクションを変更可能なコレクションに直接キャストすると、すべてのベットがオフになります。現在、例えば

listOf()これは将来変更される可能性が!Arrays.asList(T...)介して可変引数パラメータのアレイの周りにjava.util.Arrays.ArrayListを返します。この「リスト」は変更できますが、配列のサイズを変更できないため、要素を追加または削除することはできません。詳細については、Arrays.asList(T...) javadocを参照してください。

特定のコレクションから変更可能なコレクションを実際に作成する場合は、.toMutableList()を使用してコピーを作成することを検討してください。

import com.google.common.collect.ImmutableList 

fun main(args: Array<String>) { 
    val list: List<Int> = ImmutableList.of(1, 2, 3) 

    val copy = list.toMutableList() 
    copy.add(4) 

    println(copy) // [1, 2, 3, 4] 
    println(list) // [1, 2, 3] 
} 
+0

GuavaはAndroidでは避けなければなりません。 'Collections.unmodifiableList()'は最も安全で簡単な解決策です。 – WindRider

+0

@WindRider [GuavaはAndroidでうまく使用できます](http://stackoverflow.com/questions/14978699/is-it-a-good-ide-to-use-google-guava-library-for-android-開発)が、ProGuardが推奨されています – kbolino

関連する問題