`

泛型与反射的使用总结之反射篇

    博客分类:
  • java
 
阅读更多

 前一篇对泛型进行了一番总结,本篇就来说说与泛型有关的反射。
    我在泛型篇中说到了泛型在JVM中是会被擦除的,不过擦除的类还是“残留”了一些泛型的痕迹。比如Person<T>类,虽然擦除掉了泛型<T>,但是通过反射机制是可以获得这些信息的,不光如此,Person类里面定义的泛型方法都可以通过反射获得。让我们用代码来验证一下。
    在用代码验证之前,大象会对Person类稍微改造一下,增加一个泛型变量K以及一个泛型方法,其它的都保持不变。
    publicclass Person<T, K extends Comparable<? super T> & Serializable>
        extends SuperPerson<String> implements Handle<Date> {
        ......
        publicstatic <T extends Comparable<? super T>> T max(List<? extends T> list){
          Iterator<? extends T> it = list.iterator();
            T result = it.next();
            while(it.hasNext()){
                T t = it.next();
                if(t.compareTo(result) > 0)
                    result = t;
            }
            return result;
        }
        ......
    }
    下面可以开始写代码了吗?别急,大象还想先把代码中用到的几个跟反射有关的API接口说明一下,这都是JDK5.0中为泛型新增的,然后还用到了一个JDK6.0提供的Modifier,它是一个枚举类型,可以表示类、方法或字段的修饰符。
    Type
    它是所有类型的公共接口。包括原始类型、参数化类型、数组类型、类型变量和基本类型。ParameterizedType, TypeVariable, WildcardType,GenericArrayType这四个接口都是它的子接口。
    GenericDeclaration
    这个接口ClassMethodConstructor都有实现,我们就是要用这个接口的getTypeParameters方法,它返回一个TypeVariable[]数组,这个数组里面就是我们定义的类型变量TK,顺序与我们声明时一样。如果用循环语句将数组打印出来,你会发现只会输出TK,这可不是我们想要的结果,那么想要获得预期的结果怎么办呢?请继续往下看。
    TypeVariable
    它表示类型变量。比如T,比如K extendsComparable<? superT> & Serializable,这个接口里面有个getBounds()方法,它用来获得类型变量上限的Type数组,如果没有定义上限,则默认设定上限为Object,请注意TypeVariable是接口,实际得到的是TypeVariableImpl实现类,下面几个接口都一样。
    TK来说明,T没有定义任何上限,所以它就有一个默认上限java.lang.Object,实际跟踪代码的时候你会发现Tbounds属性为空,只有在调用了getBounds()方法后,才会有一个Type[1]数组[class java.lang.Object]。而对于K来说,调用了getBounds方法后,得到的数组是[java.lang.Comparable<? super T>, interface java.io.Serializable],它们的类型却是不一样的,第1个是ParameterizedType,而第二个是Class
    ParameterizedType
    ParameterizedType表示参数化类型,就是上面说的java.lang.Comparable<? super T>,再比如List<T>List<String>,这些都叫参数化类型。得到Comparable<? super T>之后,再调用getRawType()getActualTypeArguments()两个方法,就可以得到声明此参数化类型的类(java.lang.Comparable)和实际的类型参数数组([? super T]),而这个? super T又是一个WildcardType类型。
    WildcardType
    它用来描述通配符表达式,上面返回的? super T正好是这个类型。然后调用getUpperBounds()上限和getLowerBounds()下限这两个方法,获得类型变量?的限定类型(上下限),对于本例的通配符(?),它的上限为java.lang.Object,下限为T
通过上面几个接口的分析,可以将Person类的泛型参数都解析出来,那么Person的超类以及实现的接口该怎么处理呢?Class类里面同样在1.5版本加入了getGenericSuperclass()getGenericInterfaces()两个方法,用于返回带参数化类型的超类与接口。
    至此,通过上面这些接口和方法我们已经可以把class Person后面的代码都解析出来了,类里面的方法与解析类的泛型化参数类似,就不再赘述了。下图就是通过反射将定义的Person类打印出来的结果。
    
    本文主要是想通过反射机制来验证在JVM虚拟机中获得泛型的一些知识。一般实际使用的时候多数是通过反射获取超类的泛型,或者通过反射调用方法,读取/设置属性值等等这些功能,最下面有示例源码的下载。
    反 射虽然很有用处,但也不能滥用。首先用了反射就没办法在编译时进行类型检查,而且反射的代码比较复杂不容易阅读,不过好在现在有很多已经封装好的反射工具 类,帮我们做了不少这方面的工作。最后也是最重要的一点是因为,使用反射会有一定的性能损耗,就是说会比直接调用方法要慢,至于慢多少,这个不好说,但肯 定会慢,因此除非有必要,大象建议在一般情况下首先考虑用接口来代替反射。
    以上这些都是本篇关于泛型相关的反射介绍,算是一个入门知识吧,有什么不对的,或不完善的地方,还请各位指出来,谢谢!

分享到:
评论

相关推荐

    高级JAVA面试——最全的总结

    - 泛型:掌握泛型类、泛型接口、泛型方法等用法,以及类型擦除的概念。 - 多线程:理解线程的创建、同步、并发控制,如synchronized、wait()、notify()等。 - 反射:了解反射机制,如何动态调用类、方法和字段。 ...

    java高级工程师面试总结

    ### Java高级工程师面试总结 #### Java基础 - **Hashtable和HashMap的区别**: - `Hashtable`是线程安全的,而`HashMap`不是。这意味着在多线程环境中使用`Hashtable`时无需额外的同步措施,但这也使得其性能较低...

    jdk5特性总结PPT

    这份PPT(幻灯片)旨在总结和解释其中的关键特性。 1. **泛型(Generics)** 泛型允许在类、接口和方法中使用类型参数,提高了代码的类型安全性,避免了运行时类型转换异常。通过泛型,开发者可以编写更具通用性的...

    C#学习实践

    通过使用where子句,可以为类型参数添加约束,限制泛型类或方法可以使用的类型。 **11.9 从泛型类中继承** 可以从泛型类中派生出非泛型类或泛型类。 **11.10 泛型运算符** 泛型运算符允许定义可以接受任何类型...

    Java开发技术大全(500个源代码).

    DumpMethods.java 使用反射机制来获取类中的方法 getClassName.java 利用反射机制获取类的名字 invokeConstructor.java 利用反射机制调用构造器 invokeMethod.java 利用反射机制调用成员方法 listConstructors....

    Java高级编程教学幻灯片

    这组幻灯片很可能是为了深入探讨Java语言的复杂性和高级特性而设计的。以下是一些可能包含在"第8章 Java高级编程"中的关键知识点: 1. **多线程**:Java以其强大的多线程支持而闻名。在这一章中,可能讲解了如何...

    包括一些学习笔记,案例,后期还会添加java小游戏.zip

    这些笔记可能包括了Java的基础语法、面向对象的概念、核心API的使用方法、Java虚拟机(JVM)的相关知识,以及高级特性如泛型、反射、异常处理等。这类资料对于学习Java的初学者来说,是十分宝贵的参考资料,能够帮助...

    一个不错的比较全面的JAVA幻灯片

    12. **泛型**:引入泛型的概念,解释其在类、接口和方法中的使用,以及类型擦除。 13. **反射**:讲解如何在运行时动态地获取类的信息并进行操作,包括Class类的使用、构造器、方法的调用等。 14. **注解...

    java程序设计幻灯片

    11. **泛型**:学习如何使用泛型来增强代码类型安全,减少强制类型转换,并提高代码的重用性。 12. **网络编程**:讲解Socket编程,包括TCP和UDP协议,以及如何创建服务器和客户端应用程序。 13. **Java EE相关**...

    javaSE代码实例

    17.2.3 Callable与Future接口的具体使用 385 17.3 资源的封锁 386 17.3.1 Lock接口与ReentrantLock类简介 386 17.3.2 ReentrantLock锁的具体使用 387 17.3.3 ReadWriteLock接口与ReentrantReadWriteLock类...

    Java开发技术大全 电子版

    3.3成员变量的定义与使用109 3.3.1成员变量的定义109 3.3.2成员变量的访问权限110 3.3.3实例成员变量和静态成员变量114 3.4方法的定义和实现116 3.4.1方法的声明117 3.4.2创建方法体与return语句117 3.4.3...

    java 基础提高 PPT

    6. **反射机制**:通过反射,程序可以在运行时动态地获取类的信息并操作其对象。理解Class类、Constructor、Method和Field的使用,以及在实际开发中的应用。 7. **泛型**:泛型引入了类型安全,使容器能够存储特定...

    javaPPT教学课件

    15. **泛型**:理解泛型的用途,如何使用泛型类,泛型接口,泛型方法等。 16. **注解**:了解注解的定义,元注解,以及自定义注解的实现和使用。 17. **JavaFX**或Swing:对于图形用户界面(GUI)编程,可能涵盖...

    java学习幻灯片+电子教案

    4. **数组与集合框架**:介绍数组的使用,以及ArrayList、LinkedList、HashSet、HashMap等集合类的特性与操作。 5. **异常处理**:讲解如何捕获和处理程序运行时可能出现的异常,提高代码的健壮性。 6. **输入/...

    java语言程序设计ppt

    8. **泛型**:Java的泛型增加了代码的类型安全性,PPT会解释泛型的定义、使用和限制。 9. **反射**:Java的反射机制允许在运行时动态地获取类的信息和操作对象,PPT会介绍Class类、Constructor类、Method类和Field...

    《Java程序设计》 课件

    7. **泛型**:理解泛型的作用,如何在类、接口和方法中使用泛型来提高代码的类型安全性。 8. **多线程**:讲解线程的创建、同步机制(如synchronized关键字、wait()和notify()方法)以及线程池的使用。 9. **反射*...

    java学习笔记(幻灯片)

    8. **集合框架**:讲解ArrayList、LinkedList、HashSet、HashMap等集合类的使用,以及泛型的概念。 9. **IO流**:阐述输入/输出流的基本概念,包括文件读写、字节流和字符流的区别,以及缓冲区的概念。 10. **多...

    java课件PPT格式

    11. **泛型**:泛型引入了类型安全,课件会解释如何在类、接口和方法中使用泛型。 12. **反射与注解**:反射允许在运行时检查类的信息,注解则提供了元数据,课件可能讨论它们在实际编程中的应用。 13. **垃圾回收...

    java285幻灯片教程

    泛型引入了类型参数,允许在类、接口和方法中使用类型参数,增强了代码的类型安全性和重用性。 【注解(Annotation)】 注解是元数据的一种形式,提供了一种安全的方式向编译器和JVM提供信息。常用的注解有@...

Global site tag (gtag.js) - Google Analytics