`

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  

相关推荐

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

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

    泛型dao 泛型dao 泛型dao

    } 告诉对哪个类操作,如不需要自定义扩展方法就作有一个构造方法。 泛型Service:GenericService.java 与泛型dao没有区别 Service :PersonService.java 直接继承。 泛型serviceimpl与serviceimpl实现和dao层...

    JAVA上百实例源码以及开源项目源代码

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...

    java范例开发大全

    实例147 随机读写Java类文件 221 第3篇 Java面向对象编程 第8章 面向对象(教学视频:72分钟) 226 8.1 类 226 实例148 简单的通讯录类 226 实例149 简单的长度单位转换类 227 实例150 卡车和卡车司机之间的关系 229...

    Java-泛型的使用

    1.泛型 1.1 泛型的基本概念 实现了对功能代码的复用,封装,同时对数据类型进行统一的约束 格式: 1.2 泛型的使用 1.2.1 泛型在方法上的使用(使用的是静态方法) ...类声明自定义泛型,需要通过实例化

    JAVA上百实例源码以及开源项目

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...

    Java范例开发大全 (源程序)

     实例147 随机读写Java类文件 221  第3篇 Java面向对象编程  第8章 面向对象(教学视频:72分钟) 226  8.1 类 226  实例148 简单的通讯录类 226  实例149 简单的长度单位转换类 227  实例150 卡车和...

    java范例开发大全源代码

     实例147 随机读写Java类文件 221  第3篇 Java面向对象编程  第8章 面向对象(教学视频:72分钟) 226  8.1 类 226  实例148 简单的通讯录类 226  实例149 简单的长度单位转换类 227  实例150 ...

    JAVA 范例大全 光盘 资源

    实例75 自定义异常类 187 实例76 使用finally避免资源漏洞 189 实例77 反射机制 191 第10章 I/O及文件操作 196 实例78 创建文件和目录 196 实例79 查找文件 199 实例80 删除文件夹和文件 201 实例81 文件复制...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例185 自定义泛型化数组类 235 实例186 泛型方法与数据查询 236 实例187 泛型化方法与最小值 238 实例188 泛型化接口与最大值 239 实例189 使用通配符增强泛型 240 实例190 泛型化的折半查找法 241 第9章 编程常用...

    java范例开发大全(pdf&源码)

    实例147 随机读写Java类文件 221 第3篇 Java面向对象编程 第8章 面向对象(教学视频:72分钟) 226 8.1 类 226 实例148 简单的通讯录类 226 实例149 简单的长度单位转换类 227 实例150 卡车和卡车司机之间的关系 229...

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

    differ.java 测试静态方法与实例方法之间的区别 forefather.java 一个简单的基类 grandson.java 上面这个类的子类 hasConstructor.java 拥有构造器的类 hasFinalFun.java 拥有最终方法的类 hasRecall.java ...

    Java范例开发大全(全书源程序)

    实例147 随机读写Java类文件 221 第3篇 Java面向对象编程 第8章 面向对象(教学视频:72分钟) 226 8.1 类 226 实例148 简单的通讯录类 226 实例149 简单的长度单位转换类 227 实例150 卡车和卡车司机之间的...

    虚拟数据层 Struts2、Hibernate、Spring整合的泛型DAO Version 2010.9.27

    } 告诉对哪个类操作,如不需要自定义扩展方法就作有一个构造方法。 泛型Service:GenericService.java 与泛型dao没有区别 Service :PersonService.java 直接继承。 泛型serviceimpl与serviceimpl实现和dao层...

    疯狂JAVA讲义

    学生提问:为什么静态内部类实例方法也不能访问外部类的实例属性呢? 207 学生提问:接口里是否能定义内部接口? 208 6.7.3 使用内部类 208 学生提问:既然内部类是外部类的成员,是否可以为外部类定义子类,在...

Global site tag (gtag.js) - Google Analytics