kotlin 获取泛型class
时间: 2023-07-05 07:08:00 浏览: 207
可以使用 Kotlin 的反射 API 来获取泛型类,具体的代码实现如下:
```kotlin
import java.lang.reflect.ParameterizedType
class MyClass<T> {
private val type: Class<T>
init {
val superClass = javaClass.genericSuperclass as ParameterizedType
type = superClass.actualTypeArguments[0] as Class<T>
}
fun getType(): Class<T> {
return type
}
}
// 使用示例
class MySubClass : MyClass<String>()
fun main() {
val myClass = MySubClass()
println(myClass.getType()) // 输出:class java.lang.String
}
```
在上面的示例代码中,我们定义了一个泛型类 `MyClass`,并且在初始化代码块中使用了反射 API 获取了泛型类的类型,然后通过 `getType()` 方法返回了泛型类的类型。在 `MySubClass` 中我们继承了 `MyClass` 并将泛型类型指定为 `String`,最后在 `main()` 函数中打印出了泛型类的类型。
相关问题
kotlin怎么获取泛型类型
在 Kotlin 中,可以使用 reified 关键字获取泛型类型。reified 关键字可以用于内联函数中,使得我们可以在函数体内获取泛型类型的具体类型信息。
下面是一个示例代码:
```kotlin
inline fun <reified T> getType(): Class<T> {
return T::class.java
}
```
在上面的代码中,我们定义了一个内联函数 `getType`,使用 reified 关键字修饰泛型参数 `T`。在函数体内部,我们可以使用 `T::class.java` 获取泛型类型的具体类型信息。
例如,如果我们调用 `getType<Int>()`,则会返回 `java.lang.Integer` 类型的 Class 对象。
注意,使用 reified 关键字获取泛型类型的前提是,泛型参数必须在函数前面使用 inline 关键字修饰。这是因为 reified 关键字只能用于内联函数中。
请结合实例,讲解下Kotlin的泛型,像逆变,协变,out ,in等等
Kotlin中的泛型是一种类型变量的机制,它允许我们在不确定具体类型的情况下编写通用代码。Kotlin中的泛型支持协变和逆变,以及in和out的关键字。
首先,我们来看一个简单的例子,实现一个泛型容器类:
```kotlin
class Container<T>(var item: T) {
fun getItem(): T {
return item
}
}
fun main() {
val container = Container<String>("Hello")
println(container.getItem())
}
```
在这个例子中,我们定义了一个名为Container的泛型类,它有一个类型参数T。我们可以创建一个Container实例,并将其实例化为一个具体类型。我们使用getItem方法来获取这个容器中的item。
接下来,我们来介绍一下协变和逆变。假设我们有两个类:
```kotlin
open class Animal {
fun makeSound() {
println("Making animal sound")
}
}
class Cat: Animal() {
fun meow() {
println("Meow")
}
}
```
我们可以通过一个简单的示例来说明协变和逆变:
```kotlin
fun main() {
val animals: List<Animal> = listOf(Cat(), Animal())
makeSounds(animals)
}
fun makeSounds(animals: List<Animal>) {
for (animal in animals) {
animal.makeSound()
}
}
```
在这个例子中,我们定义了一个List<Animal>类型的变量animals,它包含了一个Cat和一个Animal实例。我们将这个变量传递给了makeSounds函数,该函数接受一个List<Animal>类型的参数。
在makeSounds函数中,我们使用for循环遍历animals列表,并对其中的每个Animal实例调用makeSound方法。由于Cat是Animal的子类,因此它也可以被视为Animal类型,因此我们可以将其添加到List<Animal>类型的变量中。
这里的List<Animal>类型就是协变的,因为我们可以将它的子类(如Cat)作为参数传递给makeSounds函数。
现在我们来看一下逆变。假设我们有一个接受Animal类型的参数的函数:
```kotlin
fun takeAnimal(animal: Animal) {
animal.makeSound()
}
```
我们可以将这个函数传递给另一个函数,该函数期望一个Cat类型的参数。在这种情况下,我们可以使用in关键字来表示逆变:
```kotlin
fun main() {
val cat: Cat = Cat()
takeCat(cat)
}
fun takeCat(cat: Cat) {
takeAnimal(cat)
}
fun takeAnimal(animal: Animal) {
animal.makeSound()
}
```
在这个例子中,我们定义了一个takeCat函数,它接受一个Cat类型的参数。我们将这个函数传递给了takeAnimal函数,该函数期望一个Animal类型的参数。由于Cat是Animal的子类,因此我们可以将Cat类型的参数传递给takeAnimal函数。这里的takeAnimal函数是逆变的,因为它可以接受其超类型(如Animal)的参数。
最后,我们来看一下out和in关键字。我们可以在定义泛型类型参数时使用这些关键字来限制泛型类型参数的使用方式。out关键字用于声明泛型类型参数是协变的,in关键字用于声明泛型类型参数是逆变的。
例如,我们可以定义一个只允许读取的泛型接口:
```kotlin
interface ReadOnlyContainer<out T> {
fun getItem(): T
}
```
在这个例子中,我们使用out关键字来声明泛型类型参数T是协变的。这意味着我们只能从ReadOnlyContainer接口中获取T类型的值,而不能修改它。这样做的好处是可以使我们更加安全地使用泛型类型参数。
类似地,我们可以定义一个只允许写入的泛型接口:
```kotlin
interface WriteOnlyContainer<in T> {
fun setItem(item: T)
}
```
在这个例子中,我们使用in关键字来声明泛型类型参数T是逆变的。这意味着我们只能向WriteOnlyContainer接口中设置T类型的值,而不能获取它。这样做的好处是可以避免意外修改泛型类型参数的值。
总结一下,Kotlin中的泛型支持协变和逆变,以及in和out关键字。使用协变和逆变可以使我们更加灵活地使用泛型类型参数,而使用in和out关键字可以帮助我们更加安全地使用泛型类型参数。
阅读全文