java泛型编程学习 笔记一:为什么要使用泛型

来源:互联网 发布:淘宝多个订单虚假交易 编辑:程序博客网 时间:2024/04/29 13:07

之前在参与公司RPC框架开发过程中,使用java泛型编写了RPC客户端模块的相关代码。由于泛型代码相关知识应用程序员除了在使用相关集合时有用到外,其他地方很少用到,今天是2016年元旦刚好有时间总结一下java泛型的相关知识,顺便做一下笔记方便自己回顾,也便于和大家交流学习。

(一):为什么要用泛型?

很多人会问泛型从语法层面上讲感觉很复杂,尤其是边界通配符泛型语法非常抽象,为什么要用泛型呢?

因为泛型语法相比使用Object对象实现的“泛型”可以使程序具有更好的可读性和安全性


其实泛型属于java的一种语法糖,使用泛型可以大大降低程序的复杂性提高程序的健壮性。

在java引入泛型类型之前,泛型程序设计是使用继承实现的,

/** * java 1.5添加泛型机制之前 java的泛型是通过Object进行转换的 * @author Administrator * */public class ArrayList_Object {private Object[] elementData;//...public Object get(int i){//...}public void add(Object o){//...}}
使用这种方式会带来两个问题

(1) 添加值没有类型检查,可以向数据中添加任何值

ArrayList_Object list = new ArrayList_Object();
list.add(new String("hello"));

(2)获取值时需要进行强制类型转换

String value = (String)list.get(0);


当我们在其他地方使用这个ArrayList_Object 集合时,我们并不知道集合内的元素类型,这样就会造成类型转换失败。

而java 1.5所添加的泛型机制提供了“类型参数”机制来指示元素的类型。

我们知道 在定义一个如下的普通函数时 我们会为函数提供形式参数int a和int b,这里参数a和b的名字是可以变化的,但是参数类型必须明确。

public void Method(int a, String b){//...}

而泛型的参数类型是可以不明确的,这种机制就是“类型参数”机制。


(二)泛型类和泛型方法的定义

/** * 定义一个通用的处理返回结果的泛型类 * @author Administrator * * @param <T> */public class Result<T> {private T code;private T message;public Result(T code, T message){this.code = code;this.message = message;}public T getCode() {return code;}public void setCode(T code) {this.code = code;}public T getMessage() {return message;}public void setMessage(T message) {this.message = message;}}
Result 类引入了一个类型变量T,用尖括号<> 括起来,并放在类的后面,当然如果类中的成员域如果是多个类型,我们也可以引入多个类型变量如:

public class Result<T,U> {private T code;private U message;}

泛型类的使用方法示例如下所示:

public class GenericClassLearn {public static void main(String[] args) {// TODO Auto-generated method stubGenericClassLearn gc = new GenericClassLearn();Result<String> result = gc.getResult();System.out.println("code: "+ result.getCode() + " "+ " message: "+ result.getMessage() );}/** * 定义一个方法 结果返回泛型类的对象 * @return */public static Result<String> getResult(){//do something elsereturn new Result<String>("1","success");}}

输出结果:

code: 1  message: success


除了定义泛型类之外,我们还可以定义一种带有类型参数的简单方法,这种方法既可以定义在泛型类中,又可以定义在普通类中。

/** * 泛型方法示例 * @author Administrator * */public class GenericMethod {public <T> Result<T> getResult(T ... t){System.out.println(t.length);return new Result<T>(t[0],t[1]);}public static void main(String[] args) {// TODO Auto-generated method stubGenericMethod gm = new GenericMethod();Result<String> result = gm.getResult("code:1","message:success");System.out.println("code: "+ result.getCode() + " "+ " message: "+ result.getMessage() );}}
输出结果:

2code: code:1  message: message:success

我们在普通类GenericMethod中定义了一个泛型方法getResult(T... t) ,注意类型变量<T>放在修饰符public之后,返回值Result<T>之前。

(3)类型变量的限定

我们在上例泛型方法中public <T> Result<T> getResult(T ... t)中,调用了t.length可变长参数t的length成员域,如果我们要处理某一个类族中的一个特定方法,那么

如何保证所传入的参数有这个方法呢?解决方法就是对类型参数加以约束。

我们在基类Apple中定义了一个getAppleColor()方法,然后定义子类GreenApple,并且在子类中定义了一个泛型方法

public static <T extends Apple> void getAppleColor(T apple)我们希望在泛型方法中得到任何apple的颜色,这里为了保证任何apple具有getAppleColor()方法,我们对类型参数进行了约束<T extends Apple>,使用了java中已经存在的关键字extends来进行约束。

/** * 定义包含getAppleColor()方法的基类Apple * @author Administrator * */public class Apple {private String appleColor;public String getAppleColor(){return appleColor;}}/** * GreenApple类继承Apple * @author Administrator * */public class GreenApple extends Apple{private String appleColor;public GreenApple(String appleColor){this.appleColor = appleColor;}public String getAppleColor(){return appleColor;}/** * 泛型方法中的类型参数限定为基类为Apple的类 * @param apple */public static <T extends Apple> void getAppleColor(T apple){//只有Apple的子类才具有getAppleColor()这个方法String appleColor = apple.getAppleColor();System.out.println("appleColor : " + appleColor);}public static void main(String [] args){GreenApple.getAppleColor(new GreenApple("green"));}}输出结果:appleColor : green





0 0
原创粉丝点击