读书人

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

发布时间: 2012-09-22 21:54:54 作者: rapoo

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

注:?转载请注明出处: http://hejiangtao.iteye.com,?用于商业得给我分成java泛型使用实例 - 自定义泛型类,方法

本文主要讲解道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 plaincopy
  1. /**??*?Author:?Jiangtao?He;?Email:?ross.jiangtao.he@gmail.com?
  2. ?*?Date:?2012-1-3??*?Since:?MyJavaExpert?v1.0?
  3. ?*?Description:??*/??
  4. public?class?HouseBean??{??
  5. ????private?String?brand;??????private?String?name;??
  6. ????private?String?price;?????????//省略了set/get方法??
  7. }??

CarBean.java

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

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

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

GenericGoods.java

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

?

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

[java] view plaincopy
  1. package?com.ross.generic;??import?java.lang.reflect.InvocationTargetException;??
  2. import?com.ross.generic.bean.CarBean;??import?com.ross.generic.bean.HouseBean;??
  3. /**??*?Author:?Jiangtao?He;?Email:?ross.jiangtao.he@gmail.com?
  4. ?*?Date:?2012-1-4??*?Since:?MyJavaExpert?v1.0?
  5. ?*?Description:test?the?generic?class?and?method??*/??
  6. public?class?MyMain??{??
  7. ????public?static?void?main(String[]?args)?throws?SecurityException,??????????????IllegalArgumentException,?NoSuchMethodException,??
  8. ????????????IllegalAccessException,?InvocationTargetException??????{??
  9. ????????//?Car?bean?generic?class?test??????????GenericGoods<CarBean>?oGGCar?=?new?GenericGoods<CarBean>(new?CarBean());??
  10. ????????oGGCar.setData("Mercedes",?"Benz",?"666,000?RMB");??????????System.out.println("CarBean?test:?Type?of?class?-?"??
  11. ????????????????+?oGGCar.getClassType()?+?";?Information?of?the?goods:?"??????????????????+?oGGCar.getInformation());??
  12. ??????????//?House?bean?generic?class?test??
  13. ????????GenericGoods<HouseBean>?oGGHouse?=?new?GenericGoods<HouseBean>(??????????????????new?HouseBean());??
  14. ????????oGGHouse.setData("Shenzhen?Wanke?City",??????????????????"3?rooms?with?3?restrooms?house",?"2,000,000?RMB");??
  15. ????????System.out.println("HouseBean?test:?Type?of?class?-?"??????????????????+?oGGHouse.getClassType()?+?";?Information?of?the?goods:?"??
  16. ????????????????+?oGGHouse.getInformation());??????}??
  17. }??
控制台打印信息:[java] view plaincopy
  1. CarBean?test:?Type?of?class?-?com.ross.generic.bean.CarBean;?Information?of?the?goods:?This?Benz?of?Mercedes?costs?666,000?RMB!??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 plaincopy
  1. package?com.ross.generic;??import?java.lang.reflect.Field;??
  2. import?java.lang.reflect.InvocationTargetException;??import?java.lang.reflect.Method;??
  3. /**??*?Author:?Jiangtao?He;?Email:?ross.jiangtao.he@gmail.com?
  4. ?*?Date:?2012-1-3??*?Since:?MyJavaExpert?v1.0?
  5. ?*?Description:sample?of?generic?method??*/??
  6. public?class?GenericMethodProcess??{??
  7. ????/**??????*?Author:?Jiangtao?He;?Email:?ross.jiangtao.he@gmail.com?
  8. ?????*?Date:?2012-1-3???????*?Description:??
  9. ?????*?1.?this?method?will?convert?bean?to?string?in?this?format:???????*????field_name_1=field_value_1;field_name_12=field_value_2;field_name_3=field_value_3...?
  10. ?????*?2.?The?field?of?the?bean?can?only?be?basic?java?data?type?like?'int'?or?object?type?like?'String';??????*????If?you?want?support?self-define?class?type?like?"com.ross.generic.CarBean",?you?need?extend?the?method?-:)?
  11. ?????*?@throws?NoSuchMethodException???????*?@throws?SecurityException??
  12. ?????*?@throws?InvocationTargetException???????*?@throws?IllegalAccessException??
  13. ?????*?@throws?IllegalArgumentException???????*/??
  14. ????public?<T>?String?toString(T?oT)?throws?SecurityException,??????????????NoSuchMethodException,?IllegalArgumentException,??
  15. ????????????IllegalAccessException,?InvocationTargetException??????{??
  16. ????????//?define?return?value??????????String?sRet?=?"";??
  17. ????????//?temporary?variables??????????String?sGetMethodName?=?"";??
  18. ????????String?sFieldName?=?"";??????????Method?oMethod;??
  19. ????????Field[]?oFields?=?oT.getClass().getDeclaredFields();??????????if?(null?!=?oFields)??
  20. ????????{??????????????for?(int?i?=?0;?i?<?oFields.length;?i++)??
  21. ????????????{??????????????????//?to?access?the?private?field??
  22. ????????????????oFields[i].setAccessible(true);??????????????????//?get?field?name??
  23. ????????????????sFieldName?=?oFields[i].getName();??????????????????//?get?method?name??
  24. ????????????????if?(sFieldName.length()?>?1)??????????????????{??
  25. ????????????????????sGetMethodName?=?"get"??????????????????????????????+?sFieldName.substring(0,?1).toUpperCase()??
  26. ????????????????????????????+?sFieldName.substring(1,?sFieldName.length());??????????????????}??
  27. ????????????????else??????????????????{??
  28. ????????????????????sGetMethodName?=?"get"?+?sFieldName.toUpperCase();??????????????????}??
  29. ????????????????//?get?set?method??????????????????oMethod?=?oT.getClass().getMethod(sGetMethodName);??
  30. ????????????????//?get?value??????????????????sRet?=?sRet?+?sFieldName?+?"="?+?oMethod.invoke(oT)?+?";";??
  31. ????????????}??????????}??
  32. ????????//?remove?the?last?separator:?';'??????????if?(!"".equals(sRet))??
  33. ????????{??????????????sRet?=?sRet.substring(0,?sRet.length()?-?1);??
  34. ????????}??????????return?sRet;??
  35. ????}??}??
我们写个Main函数运行 一下.
[java] view plaincopy
  1. package?com.ross.generic;??import?java.lang.reflect.InvocationTargetException;??
  2. import?com.ross.generic.bean.CarBean;??import?com.ross.generic.bean.HouseBean;??
  3. /**??*?Author:?Jiangtao?He;?Email:?ross.jiangtao.he@gmail.com?
  4. ?*?Date:?2012-1-4??*?Since:?MyJavaExpert?v1.0?
  5. ?*?Description:test?the?generic?class?and?method??*/??
  6. public?class?MyMain??{??
  7. ????public?static?void?main(String[]?args)?throws?SecurityException,??????????????IllegalArgumentException,?NoSuchMethodException,??
  8. ????????????IllegalAccessException,?InvocationTargetException??????{??
  9. ????????//?define?a?object?for?generic?method?test??????????GenericMethodProcess?oGMP?=?new?GenericMethodProcess();??
  10. ??????????//?Car?bean?generic?method?test??
  11. ????????CarBean?oCarBean?=?new?CarBean();??????????oCarBean.setBrand("Mercedes");??
  12. ????????oCarBean.setName("BMW");??????????oCarBean.setPrice("888,000?RMB");??
  13. ??????????String?sBeanStr?=?oGMP.toString(oCarBean);??
  14. ????????System.out.println("CarBean?toString:?"?+?sBeanStr);????
  15. ????????//?House?bean?generic?method?test??????????HouseBean?oHouseBean?=?new?HouseBean();??
  16. ????????oHouseBean.setBrand("Shanghai?Wanke?City");??????????oHouseBean.setName("4?rooms?with?4?restrooms?house");??
  17. ????????oHouseBean.setPrice("6,000,000?RMB");????
  18. ????????sBeanStr?=?oGMP.toString(oHouseBean);??????????System.out.println("HouseBean?toString:?"?+?sBeanStr);??
  19. ????}??}??
控制台打印信息:
[java] view plaincopy
  1. CarBean?toString:?brand=Mercedes;name=BMW;price=888,000?RMB??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");

读书人网 >编程

热点推荐