Kotlin与Java中的泛型问题

举报
yd_221104950 发表于 2020/12/02 22:36:03 2020/12/02
【摘要】 Kotlin可以在声明处或使用处解决泛型歧义 声明处解决泛型歧义 一、上界异常 1.Java泛型类 public class Box<T> { } 12 以下赋值是错误的:错误!错误!错误! 编译器会报类型不匹配的错误。 Box<Object> box1 = new Box<Object>(); Box<String...

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

声明处解决泛型歧义

一、上界异常

1.Java泛型类

public class Box<T> {
}

  
 
  • 1
  • 2

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

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

  
 
  • 1
  • 2
  • 3

解决办法,指定上界:

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

  
 
  • 1
  • 2
  • 3
  • 4

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

2.Kotlin泛型类

class Box<T> {

}

  
 
  • 1
  • 2
  • 3

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

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

  
 
  • 1
  • 2
  • 3

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

class Box<out T> {
}

  
 
  • 1
  • 2

二、下界异常

1.Java

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


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

  
 
  • 1
  • 2
  • 3
  • 4

解决办法,指定下界:

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

  
 
  • 1
  • 2
  • 3
  • 4

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

2.Kotlin

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

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

  
 
  • 1
  • 2
  • 3

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

class Box<in T> {

}

  
 
  • 1
  • 2
  • 3

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

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

使用处解决泛型歧义

一、类型推断

我们以Array来讨论。

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

  
 
  • 1
  • 2
  • 3
  • 4

如果我们有如下的方法

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

调用它:

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

  
 
  • 1
  • 2
  • 3

解决办法:

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

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

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

  
 
  • 1

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

文章来源: blog.csdn.net,作者:WongKyunban,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_40763897/article/details/107776826

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。