This is the second day of my participation in Gwen Challenge

Simple use of generics (ii) – Kotlin version

Sync code address github.com/xyz0z0/Andr…

The use of generics in Kotlin is much the same as in Java, and Kotlin preferably runs on the Jvm as well. But there are some differences in the way generics are used that come from Kotlin, and let’s take a look at some of them.

Type parameter constraints are written differently

In Java, extends denotes a type constraint; in Kotlin, it is distinguished by:.

    // Java uses extends
    public <T extends Number> int total(List<T> list){
        return 0;
    }
    // Kotlin uses:
    fun <T : Number> total(list: List<T>): Int {
        return 0
    }
Copy the code
Handling of Null type arguments

Kotlin is null-type safe, and so is generics. If you define a generic type using T, you can accept null values because the default upper bound is Any? . If you want to ensure that nullable types are not accepted, you need to use T: Any to define generics.

    fun <T> testNull1(list: List<T>){}fun <T : Any> testNull2(list: List<T>){}fun test(a){
        vallist = emptyList<String>() testNull1<String? >(list) testNull2<String>(list) }Copy the code
Inline functions and realizations

Because of the generic erase mechanism, it is impossible to determine the specific type in the process of using generics. For example, it is impossible to determine whether a type is a generic T that we define. In Kotlin, however, we can do this by inlining functions and implementing them. Of course, this is just a trick. In fact, when the inlining function is compiled, the compiler will replace the specific function call with the inline method we defined. So at this point our generic type is decided. This, of course, makes it impossible to call the method in Java, and the generic passed in must be a concrete type, not another generic.

    // This code will not compile because T cannot be used in the following statement
    fun <T> isInt(value: Int): Boolean {
        return value is T // error:Cannot check for instance of erased type: T
    }

    // This code can be used, but it must be of a specific type when called.
    inline fun <reified T> isString(value: String): Boolean {
        return value is T
    }

    fun <S : Any> test2(a) {
        isString<String>("")
        isString<S>("") // error:Cannot use 'S' as reified type parameter. Use a class instead.
    }
   
Copy the code
The asterisk projection

The * in Kotlin corresponds to the? Represents an element containing an unknown type. This type can only be used to retrieve values, not set values.

This article is a personal learning record, can not avoid mistakes or not enough in-depth understanding of technical points, but also hope for criticism and advice.