4.1 Java语言和Kotlin语言对比(2) 泛型和数组

来源:互联网 发布:高速公路客流量数据 编辑:程序博客网 时间:2024/05/18 21:11

4.1 Java语言和Kotlin语言对比(2)
注意Java中基础类型的装箱类型当用作类型参数时被映射成了平台类型。
例如,List<java.lang.Integer> 在Kotlin中被映射成List<Int!>
集合类型在Kotlin中有可能是只读或者不可变的,所以Java的集合类型被映射如下:(本表中的所有Kotlin类型都在包kotlin.collections下)

Java type Kotlin read-only type Kotlin mutable type Loaded platform type Iterator Iterator MutableIterator (Mutable)Iterator! Iterable Iterable MutableIterable (Mutable)Iterable! Collection Collection MutableCollection (Mutable)Collection! Set Set MutableSet (Mutable)Set! List List MutableList (Mutable)List! ListIterator ListIterator MutableListIterator (Mutable)ListIterator! Map Map MutableMap (Mutable)Map! Map.Entry Map.Entry MutableMap.MutableEntry (Mutable)Map.(Mutable)Entry!

Java arrays 的映射如下:

Java type Kotlin type int[] kotlin.IntArray! String[] kotlin.Array<(out) String>!

Java泛型在Kotlin中的表示

Kotlin中的泛型和Java中略有不同。(详见generics)。

  • 当把Java中的泛型类型引入到Kotlin的时候,做了如下转换。
    • Foo<? extends Bar>变成了Foo<out Bar!>!
    • Foo<? super Bar> 变成了Foo<in Bar!>!
  • Java的raw types 被转换成了star projections
    • List 变成了List<*>!。例如List<out Any?>!

和Java一样,Kotlin的泛型在运行时也不能被retained 例如,对象在被当做类型参数被传递给构造函数的时候,没有带有类型信息。 例如,ArrayList<Integer>ArrayList<Character>没有分别。这样就无法使用is-check来判断泛型。 Kotlin仅支持is-check 来判断star-projected泛型。

if (a is List<Int>) // Error: cannot check if it is really a List of Ints// butif (a is List<*>) // OK: no guarantees about the contents of the list

JavaArrays

在Kotlin中Arrays是非协变的invariant, 和Java不同。这意味着无法把Array<String> 赋值给Array<Any>, 这可以防止一些潜在的运行时错误。在Kotlin中,把一个子类的数组当做一个父类的数组传递给一个函数是不允许的,但是传递给Java函数中是可以的(通过Array<(out) String>!)。

Java平台上数组和基础数据类型被用来减少装箱/拆箱操作带来消耗。 由于Kotlin隐藏了这些实现的细节,必须要使用一个规避方法来和Java代码交互。这些就是对于每个基础数据类型数组的特殊类型(IntArray, DoubleArray, CharArray 等)。这些类型和Array类型无关,并且被编译成Java的基础数组类型来获得最好的性能。

假设下面的Java函数接受一个int 类型的数组

public class JavaArrayExample {    public void removeIndices(int[] indices) {        // code here...    }}

在Kotlin中可以传一个基础数据类型的数据当做参数

val javaObj = JavaArrayExample()val array = intArrayOf(0, 1, 2, 3)javaObj.removeIndices(array)  // passes int[] to method

当编译成JVM代码时,编译器会优化数组的访问,因此没有引入额外的开销。

val array = arrayOf(1, 2, 3, 4)array[x] = array[x] * 2 // no actual calls to get() and set() generatedfor (x in array) { // no iterator created    print(x)}

甚至在使用index 的时候,也没有额外的开销

for (i in array.indices) { // no iterator created    array[i] += 2}

最后in-checks 也没有额外的开销

if (i in array.indices) { // same as (i >= 0 && i < array.size)    print(array[i])}
原创粉丝点击