前言
1. 声明泛型
class Box<T>(t: T) {
val value = t
fun <E> genericity(value: E) {
println(value)
}
}
val box = Box(1)
val boxS = Box("string")
box.genericity("大鱼")
boxS.genericity(2017)
2. 泛型约束 : 对泛型的类型上限进行约束
fun <T : User> sort( s:T) { }
//这样参数只能是User类或继承了User的类
3. in 与 out修饰符 :in(消费者) out(生产者) 只能用于类或者接口
概念:只能读取的对象称为生产者, 那些只能写入的对象称为消费者
- out 只能用作输出,可以作为返回值类型但是无法作为入参的类型
- in 只能用作输入,可以作为入参的类型但是无法作为返回值的类型
//-----in只能被写入---
class TypedInClass<in I> {
fun inParam(i: I) {
}
}
var inAnyTypeClass = TypedInClass<Any>()
var inStrTypeClass = TypedInClass<String>()
// inAnyTypeClass=inStrTypeClass //error
// inStrTypeClass=inAnyTypeClass //ok
//------out 只能被读取---
class TypedOutClass<out O> {
fun outParam(): O? {
return null
}
}
var outAnyTypeClass = TypedOutClass<Any>()
var outStrTypeClass = TypedOutClass<String>()
// outAnyTypeClass=outStrTypeClass //ok
// outStrTypeClass = outAnyTypeClass //error
//----没有设置in 和out是不能被变体的
class TypedClass<N> {
fun param(n: N): N? {
return null
}
}
var normalAnyTypeClass = TypedClass<Any>()
var normalStrTypeClass = TypedClass<String>()
// normalAnyTypeClass=normalStrTypeClass //error
// normalStrTypeClass=normalAnyTypeClass //error
4. 星号投射
- 假如类型定义为 Foo<out T> , 其中 T 是一个协变的类型参数, 上界(upper bound)为 TUpper , Foo<> 等价于 Foo<out TUpper> . 它表示, 当 T 未知时, 你可以安全地从 Foo<> 中 读取 TUpper 类型的值.
- 假如类型定义为 Foo<in T> , 其中 T 是一个反向协变的类型参数, Foo<> 等价于 Foo<in Nothing> . 它表示, 当 T 未知时, 你不能安全地向 Foo<> 写入 任何东西.
- 假如类型定义为 Foo<T> , 其中 T 是一个协变的类型参数, 上界(upper bound)为 TUpper , 对于读取值的场合, Foo<*> 等价于 Foo<out TUpper> , 对于写入值的场合, 等价于 Foo<in Nothing> .
网友评论