0
点赞
收藏
分享

微信扫一扫

Kotlin与Java中的泛型问题

眸晓 2022-08-03 阅读 154


Kotlin可以在声明处或使用处解决泛型歧义

声明处解决泛型歧义

一、上界异常

1.Java泛型类

public class Box<T> {
}

以下赋值是错误的:错误!错误!错误!
编译器会报类型不匹配的错误。

Box<Object> box1 = new Box<Object>();
Box<String> box2 = new Box<String>();
box1 = box2;

解决办法,指定上界:

// 只接受Object或其子类
Box<? extends Object> box1 = new Box<Object>();
Box<String> box2 = new Box<String>();
box1 = box2;

Kotlin也有这样的问题,请继续往下看。

2.Kotlin泛型类

class Box<T> {

}

以下赋值是错误的:错误!错误!错误!
编译器会报类型不匹配的错误。

var b1 = Box<Any>()
var b2 = Box<String>()
b1 =

解决办法:在类型声明处用​​out​​修饰:

class Box<out T> {
}

二、下界异常

1.Java

以下超类泛型赋给子类泛型会报错,编译器无法识别出。

<String> box2 = new Box<String>();
Box<Object> box1 = new Box<Object>();
box2 = box1;

解决办法,指定下界:

// 只接受String或其超类
Box<? super String> box2 = new Box<String>();
Box<Object> box1 = new Box<Object>();
box2 = box1;

Kotlin是用下面的办法解决的。

2.Kotlin

以下超类泛型赋给子类泛型会报错,编译器无法识别出。

var b2 = Box<String>()
var b1 = Box<Any>()
b2 = b1

解决办法,在类型声明处用​​in​​修饰:

class Box<in T> {

}

小结:Java是在使用处解决歧义的,而Kotlin是声明处解决歧义的。

除此之外,Kotlin还有一种处理方式:

使用处解决泛型歧义

一、类型推断

我们以Array来讨论。

class Array<T>(val size: Int) {
fun get(index: Int): T { ... }
fun set(index: Int, value: T) { ... }
}

如果我们有如下的方法

fun copy(from: Array<Any>, to: Array<Any>) {
assert(from.size == to.size)
for (i in from.indices)
to[i] = from[i]
}

调用它:

val ints: Array<Int> = arrayOf(1, 2, 3)
val any = Array<Any>(3) { "" }
copy(ints, any) //^ type is Array<Int> but Array<Any> was expected

解决办法:

fun copy(from: Array<out Any>, to: Array<Any>) {
assert(from.size == to.size)
for (i in from.indices)
to[i] = from[i]
}

在方法处声明​​out​​​就可以解决啦。声明为out之后,意味着from中返回泛型类型(如T)的方法才能调用。
​​​Array<out Any>​​​对应于Java的​​Array<? extends Object>​​​ 除了在使用处加​​out​​外,还有加​​in​​:

fun fill(dest: Array<in String>, value: String) { ... }

​Array<in String>​​​对应于Java的​​Array<? super String>​


举报

相关推荐

0 条评论