java泛型应用实例 - 自定义泛型类,方法
近 短时间需要使用泛型,就研究了下,发现网上的问关于泛型的文章都是讲原理的, 很少有提到那里用泛型比较合适, 本文就泛型类和泛型方法的使用给出两 个典型应用场景. 例如一个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
- /**
- * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com
- * Date: 2012-1-3
- * Since: MyJavaExpert v1.0
- * Description:
- */
- public class HouseBean
- {
- private String brand;
- private String name;
- private String price;
- //省略了set/get方法
- }
CarBean.java
- package com.ross.generic.bean;
- /**
- * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com
- * Date: 2012-1-3
- * Since: MyJavaExpert v1.0
- * Description: Store Car's information
- */
- public class CarBean
- {
- private String brand;
- private String name;
- private String price;
- //省略了set/get方法
- }
Goods的泛型类也定义出来,就是类名后面加个<T>, 他的主要功能就是获取泛型实例化的类型,并返回描述信息.
setData 方法就是将实例化对象的信息设置下, 然后在泛型类的方法中进行规整(当然实际应用的时候是可以先做查询数据库等分析,然后给出完整描述,例如售后服务,品牌推广等信息); getClassType方法就是范围实例化对象的类型了, 主要是方便体验. 下面是代码:
GenericGoods.java
- package com.ross.generic;
- import java.lang.reflect.Method;
- /**
- * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com
- * Date: 2012-1-3
- * Since: MyJavaExpert v1.0
- * Description: sample of generic class
- */
- public class GenericGoods<T>
- {
- private T t;
- private String information;
- /**
- * Description: default constructor. To get an object of the generic class
- */
- public GenericGoods(T oT)
- {
- this .t = oT;
- }
- /**
- * @param sBrand: brand of the goods
- * @param sName: name of the goods
- * @param sPrice: price of the goods
- * Description: set the data for the object
- */
- public void setData(String sBrand, String sName, String sPrice)
- {
- this .information = "This " + sName + " of " + sBrand + " costs "
- + sPrice + "!" ;
- }
- public String getClassType()
- {
- return t.getClass().getName();
- }
- //省略了set/get方法
- }
我们写个Main函数运行 一下.
- package com.ross.generic;
- import java.lang.reflect.InvocationTargetException;
- import com.ross.generic.bean.CarBean;
- import com.ross.generic.bean.HouseBean;
- /**
- * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com
- * Date: 2012-1-4
- * Since: MyJavaExpert v1.0
- * Description:test the generic class and method
- */
- public class MyMain
- {
- public static void main(String[] args) throws SecurityException,
- IllegalArgumentException, NoSuchMethodException,
- IllegalAccessException, InvocationTargetException
- {
- // Car bean generic class test
- GenericGoods<CarBean> oGGCar = new GenericGoods<CarBean>( new CarBean());
- oGGCar.setData("Mercedes" , "Benz" , "666,000 RMB" );
- System.out.println("CarBean test: Type of class - "
- + oGGCar.getClassType() + "; Information of the goods: "
- + oGGCar.getInformation());
- // House bean generic class test
- GenericGoods<HouseBean> oGGHouse = new GenericGoods<HouseBean>(
- new HouseBean());
- oGGHouse.setData("Shenzhen Wanke City" ,
- "3 rooms with 3 restrooms house" , "2,000,000 RMB" );
- System.out.println("HouseBean test: Type of class - "
- + oGGHouse.getClassType() + "; Information of the goods: "
- + oGGHouse.getInformation());
- }
- }
控制台打印信息:
- RMB!
- RMB!
3. 泛型方法应用实例
同样的基于上面的房和车的Bean进行功能验证-:)
概念不要弄混了, 泛型方法不一定要在泛型类里面. 这个GenericMethodProcess 类
不是泛型类, 在其中定义了定义了我们泛型方法toString, 它的功能就是按照指定的格式将Bean转换成String (当然,这种场景我们可以实现其他的功能,比如将表数据读取到Bean中,一个泛型方法可以搞定所有表). 代码中有详细注释不在解释了,其中用到了一点反射机制,不熟悉的可以网上搜点资料了解,或关注我后续博客 .GenericMethodProcess.java
- package com.ross.generic;
- import java.lang.reflect.Field;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- /**
- * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com
- * Date: 2012-1-3
- * Since: MyJavaExpert v1.0
- * Description:sample of generic method
- */
- public class GenericMethodProcess
- {
- /**
- * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com
- * Date: 2012-1-3
- * Description:
- * 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...
- * 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 -:)
- * @throws NoSuchMethodException
- * @throws SecurityException
- * @throws InvocationTargetException
- * @throws IllegalAccessException
- * @throws IllegalArgumentException
- */
- public <T> String toString(T oT) throws SecurityException,
- NoSuchMethodException, IllegalArgumentException,
- IllegalAccessException, InvocationTargetException
- {
- // define return value
- String sRet = "" ;
- // temporary variables
- String sGetMethodName = "" ;
- String sFieldName = "" ;
- Method oMethod;
- Field[] oFields = oT.getClass().getDeclaredFields();
- if ( null != oFields)
- {
- ; i < oFields.length; i++)
- {
- // to access the private field
- oFields[i].setAccessible(true );
- // get field name
- sFieldName = oFields[i].getName();
- // get method name
- )
- {
- sGetMethodName = "get"
- ).toUpperCase()
- , sFieldName.length());
- }
- else
- {
- sGetMethodName = "get" + sFieldName.toUpperCase();
- }
- // get set method
- oMethod = oT.getClass().getMethod(sGetMethodName);
- // get value
- sRet = sRet + sFieldName + "=" + oMethod.invoke(oT) + ";" ;
- }
- }
- // remove the last separator: ';'
- if (! "" .equals(sRet))
- {
- );
- }
- return sRet;
- }
- }
我们写个Main函数运行 一下.
- package com.ross.generic;
- import java.lang.reflect.InvocationTargetException;
- import com.ross.generic.bean.CarBean;
- import com.ross.generic.bean.HouseBean;
- /**
- * Author: Jiangtao He; Email: ross.jiangtao.he@gmail.com
- * Date: 2012-1-4
- * Since: MyJavaExpert v1.0
- * Description:test the generic class and method
- */
- public class MyMain
- {
- public static void main(String[] args) throws SecurityException,
- IllegalArgumentException, NoSuchMethodException,
- IllegalAccessException, InvocationTargetException
- {
- // define a object for generic method test
- GenericMethodProcess oGMP = new GenericMethodProcess();
- // Car bean generic method test
- CarBean oCarBean = new CarBean();
- oCarBean.setBrand("Mercedes" );
- oCarBean.setName("BMW" );
- oCarBean.setPrice("888,000 RMB" );
- String sBeanStr = oGMP.toString(oCarBean);
- System.out.println("CarBean toString: " + sBeanStr);
- // House bean generic method test
- HouseBean oHouseBean = new HouseBean();
- oHouseBean.setBrand("Shanghai Wanke City" );
- oHouseBean.setName("4 rooms with 4 restrooms house" );
- oHouseBean.setPrice("6,000,000 RMB" );
- sBeanStr = oGMP.toString(oHouseBean);
- System.out.println("HouseBean toString: " + sBeanStr);
- }
- }
控制台打印信息:
- RMB
- RMB
4.泛型的一些规则和限制
1) 泛型的类型参数只能是类类型(包括自定义类),不能是基本数据类型。
2) 泛型的类型参数可以有多个。
3) 泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上称为“有界类型”。
4) 泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName("java.lang.String");
java泛型应用实例 - 自定义泛型类,方法的更多相关文章
- Java泛型学习笔记 - (二)泛型类
1. 我们先写一个没有泛型的类Box: public class Box { private Object obj; public Box() {} public Object getObj() { ...
- Java泛型(泛型接口、泛型类、泛型方法)
转载 转载出处:https://www.cnblogs.com/JokerShi/p/8117556.html 泛型接口: 定义一个泛型接口: 通过类去实现这个泛型接口的时候指定泛型T的具体类型. 指 ...
- 浅析Java泛型
什么是泛型? 泛型是JDK 1.5的一项新特性,它的本质是参数化类型(Parameterized Type)的应用,也就是说所操作的数据类型被指定为一个参数,在用到的时候在指定具体的类型.这种参数类型 ...
- java 面向对象(三十四):泛型三 自定义泛型类、泛型接口、泛型方法
1.举例: [Order.java] public class Order<T> { String orderName; int orderId; //类的内部结构就可以使用类的泛型 T ...
- 初识Java泛型以及桥接方法
泛型的由来 在编写程序时,可能会有这样的需求:容器类,比如java中常见的list等.为了使容器可以保存多种类型的数据,需要编写多种容器类,每一个容器类中规定好了可以操作的数据类型.此时可能会有Int ...
- java泛型-泛型类,泛型接口,常用形式
泛型简单使用: package com.etc; import java.util.ArrayList; import java.util.List; /* 泛型就相当于<>一个标签,泛化 ...
- java泛型-自定义泛型方法与类型推断总结
下面是自定义泛型方法的练习: package com.mari.generic; import java.util.ArrayList; import java.util.Collection; im ...
- java 泛型实例详解(普通泛型、 通配符、 泛型接口)
java 泛型详解(普通泛型. 通配符. 泛型接口) 2013-02-04 19:49:49| 分类: JAVA | 标签:java |举报|字号 订阅 下载LOFTER客户端 JDK1.5 令我们期 ...
- java 泛型 -- 泛型类,泛型接口,泛型方法
泛型T泛型的许多最佳例子都来自集合框架,因为泛型让您在保存在集合中的元素上指定类型约束.在定义泛型类或声明泛型类的变量时,使用尖括号来指定形式类型参数.形式类型参数与实际类型参数之间的关系类似于形式方 ...
随机推荐
- javascript之键盘事件
键盘事件包含onkeydown.onkeypress和onkeyup这三个事件 事件初始化 function keyDown(){} document.onkeydown = keyDown; ...
- UNIX网络编程——UDP回射服务器程序(初级版本)以及漏洞分析
该函数提供的是一个迭代服务器,而不是像TCP服务器那样可以提供一个并发服务器.其中没有对fork的调用,因此单个服务器进程就得处理所有客户.一般来说,大多数TCP服务器是并发的,而大多数UDP服务器是 ...
- open_links_per_instance 和 open_links 参数说明
1.1 OPEN_LINKS Property Description Parameter type Integer Default value 4 Modifiable No --即修改需要重启实 ...
- Android列表视图ListView和ListActivity-android学习之旅(二十四)
ListView简介 ListView是android中常用的一种控件,创建ListView有两种方式: 1.在xml中使用ListView控件创建. 2.使用activity继承ListActivi ...
- SDL2源代码分析4:纹理(SDL_Texture)
===================================================== SDL源代码分析系列文章列表: SDL2源代码分析1:初始化(SDL_Init()) SDL ...
- java设计模式---三种工厂模式之间的区别
简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式.其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性. 本文是本人对这三种模式学习后的一个小结以及对他 ...
- android sensor架构
Android Sensor 架构深入剖析 作者:倪键树,华清远见嵌入式学院讲师. 1.Android sensor架构 Android4.0系统内置对传感器的支持达13种,它们分别是:加速度传感器 ...
- 简单的C语言猜数字小游戏
猜数字小游戏可谓是C语言最为基础的一个知识点了,我们可以在此基础上进行延伸,实现随机数的猜测,然后是加入再来一局的模式,等等.这里是抛砖引玉,希望你能做出你的经典之作. #include <st ...
- Python学习笔记 - 函数参数
>>> def power(x): ... return x * x ... >>> power(5) 25 >>> def power(x, n ...
- 给Cocos2D视图添加手势支持
见如下代码: UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:self ac ...