Deep understanding of kotlin’s generic system

preface

Like Java, kotlin's generics are a kind of syntax sugar. They only appear in the source code, and simple string replacement will be performed during compilation.

Generics are an indispensable part of static type language. Kotlin's definition and use of generics are similar to Java, but there are also some optimizations and improvements based on engineering practice.

Generics is actually parameterizing types. Its real name is called type parameters. It adds more flexibility to strongly typed programming languages. In Java, as long as there are typed API elements, they can be generalized, that is, generic classes, generic interfaces, generic methods and generic attributes. Generic classes and generic interfaces can be collectively referred to as generic types. The most important ones are generic types and generic methods. Kotlin generic system inherits Java generic system and adds some enhancements.

Materialized generic parameters

This method is often defined in Java:

This is because Java's generic erasure mechanism cannot use the shape such as t.class to obtain the real type object of the generic. However, in the view of the caller, generics are real fixed types. Therefore, the generic parameters can be realized with the help of kotlin's inline function. In kotlin, you only need to:

Covariance and inversion of generics

In Java, when defining parameters with generics, in order to better match the target type, are there? Extensions type and? There are two forms of super type. Take the definition in the list interface as an example:

In the addall method, the generic type in the collection is defined as a subclass of the receiving type parameter E. This is because the value of C needs to be read, so it is necessary to ensure that C is a subclass of the collection; In the sort method, the type parameter E in the class needs to be passed in by the method in the comparator, so it is necessary to ensure that e is a subclass of the comparator type parameter.

In kotlin, two other keywords are given for these two cases: when you need to read the value of a generic object, use out to mark the type parameter; Use in when the type of the passed in type parameter is required as a formal parameter.

The naming directions of these two keywords are different: Java prefers to name in the direction of principle, while kotlin's naming is more intuitive for specific use scenarios. In kotlin, the type marked by out type parameter is called covariant type, which means that when a is a subclass of B, C can also be used as a subclass of C; On the contrary, the type of the type parameter marked by in represents that when a is a subclass of B, C is a subclass of C.

In terms of the use of method parameters, kotlin and Java seem to be no different. The difference is that kotlin can apply this definition to type definition, which is officially called declaration point variant; Correspondingly, methods defined on method parameters like Java are called usage point variants.

The declaration point variant defines whether the type parameter is used for input or output parameters when declaring a type. Then, the definition name of the type will be called directly in all places used in this class to use the covariance or inversion of the type. In Java, you need to repeatedly explain whether covariance or inversion is required every time you use it. Kotlin can also use point variants, as long as, like Java, it is not described at the declaration, but only declared at the time of use.

"*" projection

Because it is not allowed to ignore generic parameters in kotlin source code, it is inevitable to use generic parameters to represent some unimportant places. When used, in order to ensure type safety, the official recommended mode is to encapsulate the objects defined as generic types. Write operations are generally safe because all types can be received; Read operations can be safely converted, and mismatched types can be handled uniformly.

Notes on generics:

The trickiest part of the type system in Java programming is wildcard types. However, in kotlin programming, there are no wildcards, which are replaced by declaration changes and type projection.

Role of wildcards: use boundary wildcards to increase API flexibility.

A common problem in Java programming:

In kotlin programming:

Once a type is declared, no other type data can be added, as shown in the following figure.

summary

The above is the whole content of this article. I hope the content of this article has a certain reference value for your study or work. If you have any questions, you can leave a message. Thank you for your support for programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>