近 短时间需要使用泛型,就研究了下,发现网上的问关于泛型的文章都是讲原理的, 很少有提到那里用泛型比较合适, 本文就泛型类和泛型方法的使用给出两 个典型应用场景. 例如一个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

  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

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

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

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

GenericGoods.java

  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. * @param sBrand: brand of the goods
  22. * @param sName: name of the goods
  23. * @param sPrice: price of the goods
  24. * Description: set the data for the object
  25. */
  26. public   void  setData(String sBrand, String sName, String sPrice)
  27. {
  28. this .information =  "This "  + sName +  " of "  + sBrand +  " costs "
  29. + sPrice + "!" ;
  30. }
  31. public  String getClassType()
  32. {
  33. return  t.getClass().getName();
  34. }
  35. //省略了set/get方法
  36. }

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

  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. // House bean generic class test
  24. GenericGoods<HouseBean> oGGHouse = new  GenericGoods<HouseBean>(
  25. new  HouseBean());
  26. oGGHouse.setData("Shenzhen Wanke City" ,
  27. "3 rooms with 3 restrooms house" ,  "2,000,000 RMB" );
  28. System.out.println("HouseBean test: Type of class - "
  29. + oGGHouse.getClassType() + "; Information of the goods: "
  30. + oGGHouse.getInformation());
  31. }
  32. }

控制台打印信息:

  1. RMB!
  2. RMB!

3. 泛型方法应用实例

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

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

GenericMethodProcess.java

  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. ; 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. )
  48. {
  49. sGetMethodName = "get"
  50. ).toUpperCase()
  51. , 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. );
  67. }
  68. return  sRet;
  69. }
  70. }

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

  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. // Car bean generic method test
  20. CarBean oCarBean = new  CarBean();
  21. oCarBean.setBrand("Mercedes" );
  22. oCarBean.setName("BMW" );
  23. oCarBean.setPrice("888,000 RMB" );
  24. String sBeanStr = oGMP.toString(oCarBean);
  25. System.out.println("CarBean toString: "  + sBeanStr);
  26. // House bean generic method test
  27. HouseBean oHouseBean = new  HouseBean();
  28. oHouseBean.setBrand("Shanghai Wanke City" );
  29. oHouseBean.setName("4 rooms with 4 restrooms house" );
  30. oHouseBean.setPrice("6,000,000 RMB" );
  31. sBeanStr = oGMP.toString(oHouseBean);
  32. System.out.println("HouseBean toString: "  + sBeanStr);
  33. }
  34. }

控制台打印信息:

  1. RMB
  2. RMB

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

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

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

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

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


java泛型应用实例 - 自定义泛型类,方法的更多相关文章

  1. Java泛型学习笔记 - (二)泛型类

    1. 我们先写一个没有泛型的类Box: public class Box { private Object obj; public Box() {} public Object getObj() { ...

  2. Java泛型(泛型接口、泛型类、泛型方法)

    转载 转载出处:https://www.cnblogs.com/JokerShi/p/8117556.html 泛型接口: 定义一个泛型接口: 通过类去实现这个泛型接口的时候指定泛型T的具体类型. 指 ...

  3. 浅析Java泛型

    什么是泛型? 泛型是JDK 1.5的一项新特性,它的本质是参数化类型(Parameterized Type)的应用,也就是说所操作的数据类型被指定为一个参数,在用到的时候在指定具体的类型.这种参数类型 ...

  4. java 面向对象(三十四):泛型三 自定义泛型类、泛型接口、泛型方法

    1.举例: [Order.java] public class Order<T> { String orderName; int orderId; //类的内部结构就可以使用类的泛型 T ...

  5. 初识Java泛型以及桥接方法

    泛型的由来 在编写程序时,可能会有这样的需求:容器类,比如java中常见的list等.为了使容器可以保存多种类型的数据,需要编写多种容器类,每一个容器类中规定好了可以操作的数据类型.此时可能会有Int ...

  6. java泛型-泛型类,泛型接口,常用形式

    泛型简单使用: package com.etc; import java.util.ArrayList; import java.util.List; /* 泛型就相当于<>一个标签,泛化 ...

  7. java泛型-自定义泛型方法与类型推断总结

    下面是自定义泛型方法的练习: package com.mari.generic; import java.util.ArrayList; import java.util.Collection; im ...

  8. java 泛型实例详解(普通泛型、 通配符、 泛型接口)

    java 泛型详解(普通泛型. 通配符. 泛型接口) 2013-02-04 19:49:49| 分类: JAVA | 标签:java |举报|字号 订阅 下载LOFTER客户端 JDK1.5 令我们期 ...

  9. java 泛型 -- 泛型类,泛型接口,泛型方法

    泛型T泛型的许多最佳例子都来自集合框架,因为泛型让您在保存在集合中的元素上指定类型约束.在定义泛型类或声明泛型类的变量时,使用尖括号来指定形式类型参数.形式类型参数与实际类型参数之间的关系类似于形式方 ...

随机推荐

  1. A*寻路算法入门(二)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  2. ASP.NET实现网页版小优盘

    今天看到了一篇不错的文章,就拿来一起分享一下吧. 实现的是文件的上传与下载功能. 关于文件上传: 谈及文件上传到网站上,首先我们想到的就是通过什么上传呢?在ASP.NET中,只需要用FileUploa ...

  3. SimpleDateFormat用法大全及易错分析

    SimpleDateFormat 使用java语言处理日期相关操作,就不可避免的会使用到SimpleDateFormat.当然了,目前我们采用较多的是Calendar类,通过对之求相关的属性值即可得到 ...

  4. Linux之命令的组合

    在Linux下有好多经典的操作,其中尤为经典的是命令的组合,不管是作为参数,还是命令之间的配合,都做得比较完善.下面看一下常用的一些命令吧. 1.连续运行多个命令就可以使用':'作为分隔,但是缺点就是 ...

  5. iOS中 读取相册,调用系统相机 技术分享

    技术内容:分别读取相册以及调取相机,将图片显示到imageView上 布局: 1.创建imageView 和 button 并为button一个关联pickerImage的事件 <div sty ...

  6. org/w3c/dom/ElementTraversal 错误解决办法

    org/w3c/dom/ElementTraversal 错误解决办法 不记得之前几天把什么maven依赖包删除了,今天利用htmlunit运行代码的时候报了下面的错误: Exception in t ...

  7. shell,python获取当前路径(脚本的当前路径) (aso项目记录)

    一.shell获取脚本当前路径 cur_dir=$(cd "$(dirname "$0")"; pwd)  #获取当前脚本的绝对路径,参数$0是当前脚本对象 等 ...

  8. VS2008中开发手持终端程序(PDA软件)总结

    VS2008中开发手持终端程序(PDA手机软件)的项目总结 1程序结构 程序中包括四个部分: 1.系统配置 这个部分用来配置系统中的相关参数,参数包括数据库信息和串口的配置信息.这部分的主要技术是XM ...

  9. mysql进阶(十)不靠谱的FLOAT数据类型

    今天在设计数据表时,突然发现原来FLOAT原来是很不靠谱的,所以在这里建议大家换成DOUBLE类型, 原因是: 在mysql手册中讲到,在MySQL中的所有计算都是使用双精度完成的,使用float(单 ...

  10. Leetcode_80_Remove Duplicates from Sorted Array II

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/43835055 Follow up for "Re ...