相关文章推荐
豪情万千的眼镜  ·  智能指针reset()·  4 天前    · 
豪情万千的眼镜  ·  Resources·  1 月前    · 
豪情万千的眼镜  ·  python 调用打印机 ...·  9 月前    · 
豪情万千的眼镜  ·  [Answer]-How to ...·  10 月前    · 
豪情万千的眼镜  ·  Java ...·  11 月前    · 
豪情万千的眼镜  ·  MySQL 导出数据 | ·  11 月前    · 
不爱学习的火腿肠  ·  java ...·  44 分钟前    · 
旅行中的铁链  ·  错误信息:SSL ShakeHand ...·  1小时前    · 
class StudentServiceImpl extends BaseService implements StudentService { @Override int save(Student student) { return 0; @Override public List findStudent(String name, Integer age) { return Arrays.asList(new Student[]{new Student("Jack", 20), new Student("Li", 30)}); public class JDemo { public static void main(String[] args) { StudentServiceImpl studentService = new StudentServiceImpl(); studentService.save(new Student("Tom", 30)); studentService.findStudent("Jack", 20); //反射API调用示例 final Class studentServiceClass = studentService.getClass(); //getClasses得到该类及其父类所有的public的内部类。 //getDeclaredClasses得到该类所有的内部类,除去父类的。 Class[] classes = studentServiceClass.getDeclaredClasses(); Annotation[] annotations = studentServiceClass.getAnnotations(); ClassLoader classLoader = studentServiceClass.getClassLoader(); Field[] fields = studentServiceClass.getDeclaredFields(); Method[] methods = studentServiceClass.getDeclaredMethods(); try { methods[0].getName(); methods[0].invoke(studentService,"jack",20); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace();
通过反射,可以获取一个类的注解、方法、成员变量等。那么能不能通过反射获取到泛型信息呢?我们知道java中的泛型擦除。在程序运行时,无法得到自己本身的泛型信息。而当这个类继承了一个父类,父类中有泛型的信息时,那么可以通过getGenericSuperclass()方法得到一个父类的泛型信息。getGenericSuperclass()是Generic继承的特例,对于这种情况子类会保持父类的Generic参数类型。返回一个ParameterizedType。另外我们所说的java泛型在字节码中会被擦除,并不总是擦除为Object类型,而是擦除到上限类型。
在Kotlin也是一样的泛型机制。所以通过反射能拿到的也只能是有继承父类泛型信息的子类泛型。
class A<T>
open class C<T>
class B<T> : C<Int>()
fun fooA() {
    val parameterizedType = A<Int>()::class.java.genericSuperclass as ParameterizedType
    val actualTypeArguments = parameterizedType.actualTypeArguments
    for (type in actualTypeArguments) {
        val typeName = type.typeName
        println("typeName=$typeName")

运行fooA(),会报错

Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
	at com.k.d.TestKt.fooA(Test.kt:11)
	at com.k.d.Test.main(Test.kt:24)
fun fooB(){
    val parameterizedType = B<Int>()::class.java.genericSuperclass as ParameterizedType
    val actualTypeArguments = parameterizedType.actualTypeArguments
    for (type in actualTypeArguments) {
        val typeName = type.typeName
        println("typeName=$typeName")

执行下面的代码可以运行成功。

typeName=java.lang.Integer
  • 下面通过一个简单的实例来说明Kotlin中反射怎样获取泛型代码的基本信息。
* 声明一个父类 BaseContainer open class BaseContainer<T> * 声明一个Container 继承BaseContainer class Container<T : Comparable<T>> : BaseContainer<Int> { val elements: MutableList<T> constructor(elements: MutableList<T>) : super() { this.elements = elements fun sort(): Container<T> { elements.sort() return this override fun toString(): String { return "Container(elements=$elements)" object Test { @JvmStatic fun main(args: Array<String>) { //声明一个Container实例 val container = Container(mutableListOf(1, 2, 3, 4, 5)) // 获取Container的KClass对象引用 val kClazz = container::class // KClass对象的typeParameters属性中存有类型参数的信息 val typeParameters = kClazz.typeParameters //typeParameters 取数组的第一个 val kTypeParameter: KTypeParameter = typeParameters[0] // kTypeParameter有下面等属性 println(kTypeParameter.isReified) // false println(kTypeParameter.name) // T println(kTypeParameter.upperBounds) // [kotlin.Comparable<T>] println(kTypeParameter.variance) // INVARIANT val constructors = kClazz.constructors for (KFunction in constructors) { KFunction.parameters.forEach { val name = it.name val type = it.type println("name=$name") // name=elements println("type=$type") // type=kotlin.collections.MutableList<T> for (KTypeProjection in type.arguments) { println(KTypeProjection.type) // T 在java中,使用反射的代码实例如下:class Student { String name; Integer age; public Student(String name, Integer age) { this.name = name; this.age = age; } public String getN... 在Java中使用Class很常见的就是,xxx类.class,比如我们在startActivity的时候startActivity(new Intent(this, OtherActivity.class)); 这里接收的就是CLass 1、Class c = person.getClass(); //对象获...
写在开头:本人打算开始写一个Kotlin系列的教程,一是使自己记忆和理解的更加深刻,二是可以分享给同样想学习Kotlin的同学。系列文章的知识点会以《Kotlin实战》这本书中顺序编写,在将书中知识点展示出来同时,我也会添加对应的Java代码用于对比学习和更好的理解。 Kotlin教程(一)基础 Kotlin教程(二)函数 Kotlin教程(三)类、对象和接口 Kotlin教程(四)可空性 Kot...
val runtime = Runtime.getRuntime() val freeMemory = runtime.freeMemory() val totalMemory = runtime.totalMemory() println("Free memory: ${freeMemory / 1024} KB") println("Total memory: ${totalMemory / 1024} KB") `Runtime.getRuntime()`返回当前Java虚拟机的运行时对象,然后可以使用`freeMemory()`和`totalMemory()`方法分别获取可用内存和总内存。注意,这些方法返回的是字节,因此需要将结果除以1024来得到以KB为单位的内存大小。
 
推荐文章