java核心技术卷 之泛型程序设计
2017-10-16 09:25
302 查看
为什么要使用泛型程序设计
泛型程序设计(Generic programming)意味着编写的代码可以被很多不同类型的对象所重用。例如,我们并不希望为聚集String和File对象分别设计不同的类。实际上,也不需要这样做,因为一个ArrayList类可以聚集任何类型的对象。这是一个泛型程序设计的实例。
在Java中增加范型类之前,泛型程序设计是用继承实现的。AirayList类只维护一个Object引用的数组:
public class ArrayList // before generic classes
{
private Object[] elementdata;
public Object get(int i) { . . . }
public void add (Object o){..}
}
这样的实现有两个问题。当获取一个值时必须进行强制类型转换。
ArrayList files = new ArrayList();
• • •
String filename = (String) files.get(0);
此外,这里没有错误检查。对以向数组列表中添加任何类的对象。
files.add(new File(“.....”));
对于这个调用,编译和运行都不会出错。然而在其他地方,如果将get的结果强制类型转换为String类型,就会产生一个错误。 泛塑提供了一个更好的解决方案:类型参教(type parameters)。ArrayList类有一个类型参数用来指示元素的类型:
ArrayList<Stnng> files = new ArrayList<String>();
这使得代码具有更好的可读性。人们一看就知道这个数组列表中包含的是String对象。
编译器也可以很好地利用这个信息。当调用get的时候,不需要进行强制类型转换,编译器就知道返回值类型为String,而不是Object:
String filename = files.get(O);
编译器还知道ArrayList<String>中add方法有一个类型为String的参数。这将比使用 Object类型的参数安全一些。现在,编译器可以进行检查,避免插入错误类型的对象。例如:
files.add(new File(". . “)); // can only add String objects to an ArrayList<String>
是无法通过编译的。出现编译错误比类在运行时出现类的强制类型转换异常要好得多。类型参数的魅力在于:使得程序具有更好的可读性和安全性。
定义简单泛型类
一个泛型类(generic class)就是具有一个或多个类型变量的类。本章使用一个简单的 Pair类作为例子。对于这个类来说,我们只关注泛型,而不会为数据存储的细节烦恼。下面是Pair类的代码:
public class Pair<T>
{
private T first;
private T second;
public Pair() { first = null; second = null; }
public Pair(T first, T second) { this.first = first; this.second = second; }
public T getFirst() { return first; }
public T getSecond() { return second; }
public void setFirst(T newValue) { first = newValue; }
public void setSecond(T newValue) { second = newValue; }
}
Pair类引入了 一个类型变量T,用尖括号(<>)括起来,并放在类名的后面。泛型类可以有多个类型变量。例如,可以定义Pair类,其中第一个域和第二个域使用不同的类型:
public class Pair<T, U> { . . . }
类定义中的类型变量指定方法的返冋类型以及域和局部变量的类型。例如:
private T first; // uses the type variable
用具体的类型替换类型变量就可以实例化泛型类。例如:
Pair<String>
时以将结果想象成带有构造器的普通类:
Pai r<String>()
Pair<String>(String, String)
和方法:
String get First ()
String getSecond()
void setFirst (String)
void setSecond(String)
换句话说,泛型类可看作普通类的工厂。
程序清单中的程序使用了 Pair类。静态的minmax方法遍历了数组并同时计算出最小值和最大值。它用一个Pair对象返回了两个结果。回想一下compareTo方法比较两个字符 串,如果字符串相同则返冋0;如果按照字典顺序,第一个字符串比第二个字符串靠前,就返回负值,否则,返回正值。
示例代码:
Pair类:
PairTest1类
运行结果:
泛型程序设计(Generic programming)意味着编写的代码可以被很多不同类型的对象所重用。例如,我们并不希望为聚集String和File对象分别设计不同的类。实际上,也不需要这样做,因为一个ArrayList类可以聚集任何类型的对象。这是一个泛型程序设计的实例。
在Java中增加范型类之前,泛型程序设计是用继承实现的。AirayList类只维护一个Object引用的数组:
public class ArrayList // before generic classes
{
private Object[] elementdata;
public Object get(int i) { . . . }
public void add (Object o){..}
}
这样的实现有两个问题。当获取一个值时必须进行强制类型转换。
ArrayList files = new ArrayList();
• • •
String filename = (String) files.get(0);
此外,这里没有错误检查。对以向数组列表中添加任何类的对象。
files.add(new File(“.....”));
对于这个调用,编译和运行都不会出错。然而在其他地方,如果将get的结果强制类型转换为String类型,就会产生一个错误。 泛塑提供了一个更好的解决方案:类型参教(type parameters)。ArrayList类有一个类型参数用来指示元素的类型:
ArrayList<Stnng> files = new ArrayList<String>();
这使得代码具有更好的可读性。人们一看就知道这个数组列表中包含的是String对象。
编译器也可以很好地利用这个信息。当调用get的时候,不需要进行强制类型转换,编译器就知道返回值类型为String,而不是Object:
String filename = files.get(O);
编译器还知道ArrayList<String>中add方法有一个类型为String的参数。这将比使用 Object类型的参数安全一些。现在,编译器可以进行检查,避免插入错误类型的对象。例如:
files.add(new File(". . “)); // can only add String objects to an ArrayList<String>
是无法通过编译的。出现编译错误比类在运行时出现类的强制类型转换异常要好得多。类型参数的魅力在于:使得程序具有更好的可读性和安全性。
定义简单泛型类
一个泛型类(generic class)就是具有一个或多个类型变量的类。本章使用一个简单的 Pair类作为例子。对于这个类来说,我们只关注泛型,而不会为数据存储的细节烦恼。下面是Pair类的代码:
public class Pair<T>
{
private T first;
private T second;
public Pair() { first = null; second = null; }
public Pair(T first, T second) { this.first = first; this.second = second; }
public T getFirst() { return first; }
public T getSecond() { return second; }
public void setFirst(T newValue) { first = newValue; }
public void setSecond(T newValue) { second = newValue; }
}
Pair类引入了 一个类型变量T,用尖括号(<>)括起来,并放在类名的后面。泛型类可以有多个类型变量。例如,可以定义Pair类,其中第一个域和第二个域使用不同的类型:
public class Pair<T, U> { . . . }
类定义中的类型变量指定方法的返冋类型以及域和局部变量的类型。例如:
private T first; // uses the type variable
用具体的类型替换类型变量就可以实例化泛型类。例如:
Pair<String>
时以将结果想象成带有构造器的普通类:
Pai r<String>()
Pair<String>(String, String)
和方法:
String get First ()
String getSecond()
void setFirst (String)
void setSecond(String)
换句话说,泛型类可看作普通类的工厂。
程序清单中的程序使用了 Pair类。静态的minmax方法遍历了数组并同时计算出最小值和最大值。它用一个Pair对象返回了两个结果。回想一下compareTo方法比较两个字符 串,如果字符串相同则返冋0;如果按照字典顺序,第一个字符串比第二个字符串靠前,就返回负值,否则,返回正值。
示例代码:
Pair类:
/** * @version 1.00 2004-05-10 * @author Cay Horstmann */ public class Pair<T> { public Pair() { first = null; second = null; } public Pair(T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public T getSecond() { return second; } public void setFirst(T newValue) { first = newValue; } public void setSecond(T newValue) { second = newValue; } private T first; private T second; }
PairTest1类
/** * Created by IBM on 2017/10/16. */ public class PairTest1 { public static void main(String[] args) { String[] words = { "Mary", "Ahad", "a", "little", "lamb" }; Pair<String> mm = ArrayAlg.minmax(words); System.out.println("min = " + mm.getFirst()); System.out.println("max = " + mm.getSecond()); } } class ArrayAlg{ public static Pair<String>minmax(String[] a){ if (a == null || a.length == 0) return null; String min=a[0]; String max=a[0]; for (int i=0;i<a.length;i++){ if(min.compareTo(a[i])>0)min=a[i]; if(max.compareTo(a[i])<0)max=a[i]; } return new Pair<>(min,max); } }
运行结果:
相关文章推荐
- Java核心技术卷I:基础知识(原书第8版):12.3 泛型方法
- 【java核心技术卷一】泛型程序设计
- Java核心技术(五) —— 泛型程序设计(2)
- [学习笔记] Java核心技术 卷一:基础知识 泛型程序设计(五)
- java核心技术卷 之泛型方法
- Java核心技术(五) —— 泛型程序设计(1)
- JAVA基础【8.1】《Java核心技术1》泛型程序设计-泛型
- Java核心技术卷I:基础知识(原书第8版):12.9 反射和泛型
- Java核心技术卷I:基础知识(原书第8版):12.5 泛型代码和虚拟机
- java - 泛型程序设计(二)
- 关于JAVA核心技术的泛型一章
- Java核心技术卷I:基础知识(原书第8版):13.5 遗留的集合
- JAVA 泛型总结(结合JAVA核心技术和Effective Java两书)
- java核心之泛型(三)约束
- java核心技术卷 之处理按钮点击事件
- Java语言程序设计-进阶篇(二)泛型
- java5核心基础泛型(2):泛型在反射中的应用
- Java核心技术(Java白皮书)卷Ⅰ 第一章 Java程序设计概述
- Java的泛型程序设计
- Java核心技术 卷1 读书笔记 (3 Java基本程序设计结构)