`

java泛型应用实例 - 自定义泛型类,方法

    博客分类:
  • java
阅读更多

注: 转载请注明出处: http://hejiangtao.iteye.com 用于商业得给我分成大笑

本文主要讲解道 java泛型类,泛型方法的应用实例 , 从 这里 可以下载到完整的java代码工程:   http://download.csdn.net/detail/hejiangtao/3996520

 

近 短时间需要使用泛型,就研究了下,发现网上的问关于泛型的文章都是讲原理的, 很少有提到那里用泛型比较合适, 本文就泛型类和泛型方法的使用给出两 个典型应用场景. 例如一个toString的泛型方法,就可以将所有的Bean按照指定格式转换成字符串, 就可以避免每个Bean都要实现toString方法.

1. 先简单说两句我对泛型的理解

泛型的本质就是将数据类型也参数化, 普通方法的输入参数的值是可以变的,但是类型(比如: String)是不能变的,它使得了在面对不同类型的输入参数的时候我们要重载方法才行. 泛型就是将这个数据类型也搞成跟参数的值一样可以变的.

泛型分为泛型接口,泛型类和泛型方法. 泛型接口,泛型类大家都比较熟悉了,应该都用过List, ArrayList. List就是泛型接口,ArrayList就是泛型类, 我们经常看到List <E>的声明, new ArrayList<E>()的定义, 这里面的E可以是String, 也可以自己定义的类(例如: CarBean). 我感觉泛型类就JDK提供的就基本够用了,自定义使用的场景非常少了. 反而是泛型方法,对与解析自定义数据结构非常有用, 类似于toString这种场景是百试不爽.

java泛型的性能应该是没有问题的,说白了就是JDK做了个类型转换呗,很多网友就验证过, 我懒得验了,感兴趣的可以参考下我转载的这篇文章: http://blog.csdn.net/hejiangtao/article/details/7173838

2. 泛型类应用实例(泛型接口不再举例,跟类差不多) 

我理解泛型类就是简化版的extend 或者overwrite, 例如ArrayList, 如果对象需要add, getIndex等数组操作就可以生成一个该对象的ArrayList, 使用扩展或者重写可以实现,但是明显泛型要简便的多,定义个新对象就搞定了.

泛型类实例就是延续这个思路, 车和房子都有品牌,名字和价钱,都是商品或者货物这种数据结构,一般需要获取品牌,名字和价钱的描述信息. 我就将货物定义为泛型类,获取描述信息就是泛型类里面的通用方法.

房和车的Bean先贴出来,一看就明白,不赘述了.

HouseBean.java

[java] view plain copy
  1. /**  
  2.  * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com  
  3.  * Date: 2012-1-3  
  4.  * Since: MyJavaExpert v1.0  
  5.  * Description:  
  6.  */   
  7. public   class  HouseBean  
  8. {  
  9.     private  String brand;  
  10.     private  String name;  
  11.     private  String price;     
  12.     //省略了set/get方法   
  13. }  

CarBean.java

[java] view plain copy
  1. package  com.ross.generic.bean;  
  2.   
  3. /**  
  4.  * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com  
  5.  * Date: 2012-1-3  
  6.  * Since: MyJavaExpert v1.0  
  7.  * Description: Store Car's information  
  8.  */   
  9. public   class  CarBean  
  10. {  
  11.     private  String brand;  
  12.     private  String name;  
  13.     private  String price;  
  14.    //省略了set/get方法   
  15. }  

Goods的泛型类也定义出来,就是类名后面加个<T>, 他的主要功能就是获取泛型实例化的类型,并返回描述信息.

setData 方法就是将实例化对象的信息设置下, 然后在泛型类的方法中进行规整(当然实际应用的时候是可以先做查询数据库等分析,然后给出完整描述,例如售后服务,品牌推广等信息); getClassType方法就是范围实例化对象的类型了, 主要是方便体验. 下面是代码:

GenericGoods.java

[java] view plain copy
  1. package  com.ross.generic;  
  2. import  java.lang.reflect.Method;  
  3. /**  
  4.  * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com  
  5.  * Date: 2012-1-3  
  6.  * Since: MyJavaExpert v1.0  
  7.  * Description: sample of generic class  
  8.  */   
  9. public   class  GenericGoods<T>  
  10. {  
  11.     private  T t;  
  12.     private  String information;  
  13.     /**  
  14.      * Description: default constructor. To get an object of the generic class  
  15.      */   
  16.     public  GenericGoods(T oT)  
  17.     {  
  18.         this .t = oT;  
  19.     }  
  20.   
  21.     /**  
  22.      * @param sBrand: brand of the goods  
  23.      * @param sName: name of the goods  
  24.      * @param sPrice: price of the goods  
  25.      * Description: set the data for the object   
  26.      */   
  27.     public   void  setData(String sBrand, String sName, String sPrice)  
  28.     {  
  29.         this .information =  "This "  + sName +  " of "  + sBrand +  " costs "   
  30.                 + sPrice + "!" ;  
  31.     }  
  32.     public  String getClassType()  
  33.     {  
  34.         return  t.getClass().getName();  
  35.     }  
  36. //省略了set/get方法   
  37. }  

 

我们写个Main函数运行 一下.

[java] view plain copy
  1. package  com.ross.generic;  
  2. import  java.lang.reflect.InvocationTargetException;  
  3. import  com.ross.generic.bean.CarBean;  
  4. import  com.ross.generic.bean.HouseBean;  
  5. /**  
  6.  * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com  
  7.  * Date: 2012-1-4  
  8.  * Since: MyJavaExpert v1.0  
  9.  * Description:test the generic class and method  
  10.  */   
  11. public   class  MyMain  
  12. {  
  13.     public   static   void  main(String[] args)  throws  SecurityException,  
  14.             IllegalArgumentException, NoSuchMethodException,  
  15.             IllegalAccessException, InvocationTargetException  
  16.     {  
  17.         // Car bean generic class test   
  18.         GenericGoods<CarBean> oGGCar = new  GenericGoods<CarBean>( new  CarBean());  
  19.         oGGCar.setData("Mercedes" "Benz" "666,000 RMB" );  
  20.         System.out.println("CarBean test: Type of class - "   
  21.                 + oGGCar.getClassType() + "; Information of the goods: "   
  22.                 + oGGCar.getInformation());  
  23.   
  24.         // House bean generic class test   
  25.         GenericGoods<HouseBean> oGGHouse = new  GenericGoods<HouseBean>(  
  26.                 new  HouseBean());  
  27.         oGGHouse.setData("Shenzhen Wanke City" ,  
  28.                 "3 rooms with 3 restrooms house" "2,000,000 RMB" );  
  29.         System.out.println("HouseBean test: Type of class - "   
  30.                 + oGGHouse.getClassType() + "; Information of the goods: "   
  31.                 + oGGHouse.getInformation());  
  32.     }  
  33. }  
控制台打印信息:
[java] view plain copy
  1. CarBean test: Type of  class  - com.ross.generic.bean.CarBean; Information of the goods: This Benz of Mercedes costs  666 , 000  RMB!  
  2. HouseBean test: Type of class  - com.ross.generic.bean.HouseBean; Information of the goods: This  3  rooms with  3  restrooms house of Shenzhen Wanke City costs  2 , 000 , 000  RMB!  

3. 泛型方法应用实例

同样的基于上面的房和车的Bean进行功能验证-:)

概念不要弄混了, 泛型方法不一定要在泛型类里面. 这个GenericMethodProcess 类 不是泛型类, 在其中定义了定义了我们泛型方法toString, 它的功能就是按照指定的格式将Bean转换成String (当然,这种场景我们可以实现其他的功能,比如将表数据读取到Bean中,一个泛型方法可以搞定所有表). 代码中有详细注释不在解释了,其中用到了一点反射机制,不熟悉的可以网上搜点资料了解,或关注我后续博客 .

GenericMethodProcess.java

[java] view plain copy
  1. package  com.ross.generic;  
  2. import  java.lang.reflect.Field;  
  3. import  java.lang.reflect.InvocationTargetException;  
  4. import  java.lang.reflect.Method;  
  5. /**  
  6.  * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com  
  7.  * Date: 2012-1-3  
  8.  * Since: MyJavaExpert v1.0  
  9.  * Description:sample of generic method  
  10.  */   
  11. public   class  GenericMethodProcess  
  12. {  
  13.     /**  
  14.      * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com  
  15.      * Date: 2012-1-3   
  16.      * Description:   
  17.      * 1. this method will convert bean to string in this format:   
  18.      *    field_name_1=field_value_1;field_name_12=field_value_2;field_name_3=field_value_3...  
  19.      * 2. The field of the bean can only be basic java data type like 'int' or object type like 'String';  
  20.      *    If you want support self-define class type like "com.ross.generic.CarBean", you need extend the method -:)  
  21.      * @throws NoSuchMethodException   
  22.      * @throws SecurityException   
  23.      * @throws InvocationTargetException   
  24.      * @throws IllegalAccessException   
  25.      * @throws IllegalArgumentException   
  26.      */   
  27.     public  <T> String toString(T oT)  throws  SecurityException,  
  28.             NoSuchMethodException, IllegalArgumentException,  
  29.             IllegalAccessException, InvocationTargetException  
  30.     {  
  31.         // define return value   
  32.         String sRet = "" ;  
  33.         // temporary variables   
  34.         String sGetMethodName = "" ;  
  35.         String sFieldName = "" ;  
  36.         Method oMethod;  
  37.         Field[] oFields = oT.getClass().getDeclaredFields();  
  38.         if  ( null  != oFields)  
  39.         {  
  40.             for  ( int  i =  0 ; i < oFields.length; i++)  
  41.             {  
  42.                 // to access the private field   
  43.                 oFields[i].setAccessible(true );  
  44.                 // get field name   
  45.                 sFieldName = oFields[i].getName();  
  46.                 // get method name   
  47.                 if  (sFieldName.length() >  1 )  
  48.                 {  
  49.                     sGetMethodName = "get"   
  50.                             + sFieldName.substring(0 1 ).toUpperCase()  
  51.                             + sFieldName.substring(1 , sFieldName.length());  
  52.                 }  
  53.                 else   
  54.                 {  
  55.                     sGetMethodName = "get"  + sFieldName.toUpperCase();  
  56.                 }  
  57.                 // get set method   
  58.                 oMethod = oT.getClass().getMethod(sGetMethodName);  
  59.                 // get value   
  60.                 sRet = sRet + sFieldName + "="  + oMethod.invoke(oT) +  ";" ;  
  61.             }  
  62.         }  
  63.         // remove the last separator: ';'   
  64.         if  (! "" .equals(sRet))  
  65.         {  
  66.             sRet = sRet.substring(0 , sRet.length() -  1 );  
  67.         }  
  68.         return  sRet;  
  69.     }  
  70. }  
我们写个Main函数运行 一下.
[java] view plain copy
  1. package  com.ross.generic;  
  2. import  java.lang.reflect.InvocationTargetException;  
  3. import  com.ross.generic.bean.CarBean;  
  4. import  com.ross.generic.bean.HouseBean;  
  5. /**  
  6.  * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com  
  7.  * Date: 2012-1-4  
  8.  * Since: MyJavaExpert v1.0  
  9.  * Description:test the generic class and method  
  10.  */   
  11. public   class  MyMain  
  12. {  
  13.     public   static   void  main(String[] args)  throws  SecurityException,  
  14.             IllegalArgumentException, NoSuchMethodException,  
  15.             IllegalAccessException, InvocationTargetException  
  16.     {  
  17.         // define a object for generic method test   
  18.         GenericMethodProcess oGMP = new  GenericMethodProcess();  
  19.   
  20.         // Car bean generic method test   
  21.         CarBean oCarBean = new  CarBean();  
  22.         oCarBean.setBrand("Mercedes" );  
  23.         oCarBean.setName("BMW" );  
  24.         oCarBean.setPrice("888,000 RMB" );  
  25.   
  26.         String sBeanStr = oGMP.toString(oCarBean);  
  27.         System.out.println("CarBean toString: "  + sBeanStr);  
  28.   
  29.         // House bean generic method test   
  30.         HouseBean oHouseBean = new  HouseBean();  
  31.         oHouseBean.setBrand("Shanghai Wanke City" );  
  32.         oHouseBean.setName("4 rooms with 4 restrooms house" );  
  33.         oHouseBean.setPrice("6,000,000 RMB" );  
  34.   
  35.         sBeanStr = oGMP.toString(oHouseBean);  
  36.         System.out.println("HouseBean toString: "  + sBeanStr);  
  37.     }  
  38. }  
控制台打印信息:
[java] view plain copy
  1. CarBean toString: brand=Mercedes;name=BMW;price= 888 , 000  RMB  
  2. HouseBean toString: brand=Shanghai Wanke City;name=4  rooms with  4  restrooms house;price= 6 , 000 , 000  RMB  

4.泛型的一些规则和限制

1) 泛型的类型参数只能是类类型(包括自定义类),不能是基本数据类型。

2) 泛型的类型参数可以有多个。

3) 泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上称为“有界类型”。

4) 泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName("java.lang.String");

2
0
分享到:
评论
1 楼 xianghanscce 2014-12-11  

相关推荐

    实例185 - 自定义泛型化数组类

    总结起来,"实例185 - 自定义泛型化数组类"是关于如何利用Java泛型特性创建安全且灵活的数组容器的一个案例。通过理解泛型、数组的限制以及如何结合两者,我们可以编写出更强大、更安全的代码,提升代码的复用性和...

    实例讲解Java泛型编程的快速入门

    泛型在Java中主要应用于类、接口和方法,使得程序员可以在编译时检查类型安全,并且可以消除运行时的类型检查和强制转换。 1. **泛型的基本概念** - 类型参数:在类或接口声明中,类型参数(如`K`, `V`)代表一种...

    泛型实例<匿名方法实现排序与查找>

    总之,这个“泛型实例&lt;匿名方法实现排序与查找&gt;”是一个很好的实践,它涵盖了C#编程中的一些重要概念,包括泛型的使用、匿名方法的定义以及如何在实际应用中结合这两者进行数据操作。通过这个实例,你不仅能深化对...

    java泛型技术之发展

    本篇文章将深入探讨Java泛型的发展历程、核心概念以及其在实际开发中的应用。 1. **发展历程** - **早期版本的局限**:在Java泛型出现之前,程序员通常使用Object作为容器类(如ArrayList、HashMap等)的默认类型...

    java泛型,java知识

    Java泛型是JDK 1.5引入的重要特性,它为Java编程提供了类型安全的集合框架,使得在编译时期就能进行类型检查,避免了运行时的类型转换风险,极大地提高了代码的可读性和健壮性。泛型的引入是为了在不牺牲面向对象...

    JAVA学习笔试(数据基础+泛型编程)-适合小白

    本笔记主要涵盖了数据基础和泛型编程两大主题,同时也涉及到类和对象、数据类型、类的初始化和加载以及单例模式等多个知识点。 1. **数据基础** - **形参实参的使用**:在函数调用时,形参是方法定义中的参数,而...

    实例183 - 自定义非泛型栈结构

    标题“实例183 - 自定义非泛型栈结构”涉及的是编程中的数据结构实现,具体是栈(Stack)这一概念。栈是一种线性数据结构,遵循“后进先出”(Last In First Out, LIFO)的原则。在这个实例中,我们将探讨如何不使用...

    Java泛型技术之发展.pdf

    本篇文章将深入探讨Java泛型的发展历程、核心概念以及其在实际开发中的应用。 1. **发展历程** Java泛型的引入是为了解决早期版本中类型转换频繁和潜在的ClassCastException问题。在Java泛型出现之前,集合框架...

    java泛型学习ppt

    Java 泛型是 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型...

    Dart中的泛型 泛型方法 泛型类 泛型接口、库 自定义库、系统库、第三方库.zip

    3. **泛型接口**:虽然Dart没有像Java或C#那样明确定义接口的语法,但通过抽象类或带有抽象方法的类,我们可以实现类似的功能。泛型接口通常用于定义一组操作,这些操作可以应用于不同类型的对象。例如,`abstract ...

    JAVA核心编程技术-前十章8.ppt

    但是与方法中的参数不同,泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。 Java泛型基本概念 ------------------- ### 1. 设置通配符的上限 在Java 5.0中,引入泛型后extends关键字有了另外的含义...

    java泛型的应用

    自定义泛型类也是泛型的一个重要应用,允许我们为自己的类和接口添加类型参数,以确保它们在操作数据时遵循特定的类型规则。自定义泛型类时,需要在类名后面的尖括号`&lt;&gt;`中声明类型参数,然后在类的方法或成员中使用...

    链表+泛型+反射实现自定义的LinkedList集合类

    本资源通过实现一个自定义的LinkedList集合类,深入探讨了如何将链表、泛型和反射这三个关键知识点结合在一起。 首先,链表在Java中的标准实现是`java.util.LinkedList`类,它提供了添加、删除、查找等操作,支持...

    java泛型集合 java集合 集合 java Collection

    对于自定义类,我们可以在类中实现`Comparable`接口,重写`compareTo()`方法来定义元素之间的比较规则。或者,我们可以在排序时传入一个`Comparator`实例。 总的来说,Java泛型集合和集合框架提供了强大的数据存储...

    Java泛型与容器详细笔记.pdf (带书签)

    总结来说,Java泛型与容器详细笔记提供了关于如何使用Java中的泛型和容器类的深入理解,涵盖了Java集合框架的核心组件,泛型的类型安全机制,以及一些提高开发效率的第三方库。文档通过实例代码展示了如何在实际项目...

    java 一个关于泛型的简单例子

    泛型是Java编程语言中的一个重要特性,它引入于JDK 5.0,极大地提高了代码的类型安全性和可读性。...在实际项目中,泛型广泛应用于集合框架(如List、Set、Map等),以及自定义的数据结构和算法实现中。

    Java基础篇:泛型.pdf

    Java泛型的一个重要应用是在集合框架中。在JDK 1.5之前,Java集合类框架使用Object作为元素类型,这意味着集合可以存储任何类型的对象。然而,这种设计导致在从集合中获取元素时必须进行类型转换,这个过程是繁琐且...

    jdk5.zip_java 泛型_jdk5 泛型_泛型

    Java泛型在运行时会被擦除,因此泛型不提供运行时的类型检查。所有的泛型类和方法都会有一个没有泛型的等价形式,这个过程称为类型擦除。 4. **通配符的使用**: - 无界通配符:`?`,表示类型参数可以是任何类型...

    Java语言程序设计教程课件第五章泛型和枚举

    泛型可以应用于集合框架、自定义类、接口和方法等场景,是Java编程中的高级特性。本部分内容将详细介绍泛型的基本概念、定义、用法和规则限制等。 首先,泛型的基本概念是“参数化类型”,它允许程序员在不明确指定...

Global site tag (gtag.js) - Google Analytics