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

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

Java typeKotlin read-only typeKotlin mutable typeLoaded platform type
IteratorIteratorMutableIterator(Mutable)Iterator!
IterableIterableMutableIterable(Mutable)Iterable!
CollectionCollectionMutableCollection(Mutable)Collection!
SetSetMutableSet(Mutable)Set!
ListListMutableList(Mutable)List!
ListIteratorListIteratorMutableListIterator(Mutable)ListIterator!
MapMapMutableMap(Mutable)Map!
Map.EntryMap.EntryMutableMap.MutableEntry(Mutable)Map.(Mutable)Entry!

Java arrays 的映射如下:

Java typeKotlin 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
// but
if (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() generated
for (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])
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值