Article Directory
Type parameter
Generics allow the definition of types with type parameters . When an instance of this type is created, the type parameters are replaced with concrete types called type arguments
Instance
// 源码listOf函数声明
fun <T> listOf(vararg elements: T): List<T>
val list=listOf("hello","world") // 编译器推导
val list= listOf<String>()// 显示说明
In the above example, T is a type parameter , and the return type of the function uses a type parameter
the difference
- Kotlin requires that type arguments are either explicitly specified or can be deduced by the compiler
- Kotlin does not support primitive types, the type arguments must be defined
- Java allows the use of generic types without type parameters (original ecological types) because it supports compatibility with older versions of code
Generic classes and functions
Generic class
Kotlin declares generic classes and generic interfaces by adding a pair of sharp check marks after the class name and putting the type parameters within the sharp check marks. Once declared, type parameters can be used in the body of the class like other types.
// 泛型类
class Gen<T>(private var t: T) {
fun getValue() :T{
return t
}
}
// 泛型接口
interface List<T>{
public operator fun get(index: Int): T
}
Summary: If the class inherits the generic class (implements the generic interface), it must provide a type argument for the generic parameter of the base type , which can be a concrete type or another type parameter:
class GenList:List<String>{
override fun get(index :Int):String=...
}
class ArrayList<T>:List<T>{
override fun get(index :Int):T=...
}
Generic function
Generic functions have their own type parameters , these type parameters must be replaced with specific type arguments each time the function is called
fun <T> printMessage(msg :T){
when (content) {
is Int ->{
"该信息数据类型是整型"}
else ->{
"该信息数据类型不是整型"}
}
}
Note: Ordinary (ie, non-extended) attributes cannot have type parameters, and cannot store multiple values of different types in the attributes of a class, so there is no point in declaring generic non-extended functions
Type parameter constraints
Type parameter constraints may limit the generic functions and generic class as the type argument type; if the specified type is a generic type of the upper bound constraint parameter, in particular the initializing generic type, which corresponds to the type of solid The parameter must be this concrete type or its subtype
Example
// 函数声明
fun <T:Number> List<T>.sum() :T
// 具体类型实参继承了Number,函数调用是允许的
println(listOf(1,2,3).sum())
In the above example, the constraint is defined by specifying the upper bound after the type parameter. Put the colon after the name of the type parameter, and the type as the upper bound of the type parameter immediately follows; once the upper bound of the type parameter T is specified, you can Use the value of type T as the value of its upper bound (type)
The type parameter is not empty or nullable
If the declaration is a generic class or generic function, any type argument, including those nullable type arguments, can replace its type parameters; type parameters without an upper bound will use the default Any? Upper Bound
// 类型参数可空 默认上界的类型形参是Any?
class Person<T>{
fun name(value :T){
value?.hashcode()
}
}
// 类型参数非空 默认上界的类型形参是Any
class Person<T:Any>{
fun name(value :T){
value?.hashcode()
}
}
Note : You can make the type parameter non-null by specifying any non-empty type as the upper bound, not just the type Any