论文部分内容阅读
[摘要]Java编程中,在遇到对象存取问题时,传统方法采用以Object类为中介,进行类型转换,导致代码可读性差,并常常导致出现运行时的转型异常,且该类错误很难在编译期被发现。采用Java的泛型机制,可以极大的提高程序的可读性与安全性,使程序得以正常运行。
[关键词]Java 泛型 转型
中图分类号:TP3文献标识码:A 文章编号:1671-7597 (2008) 0210022-02
Java中的泛型是JDK1.5的新特性,在1.5及以后的版本中被支持。在Java编程中,常常用到在容器中存放对象或从容器中取出对象,并根据实际情况转型为相应的对象,但在转型过程中极易出现错误,且很难发现。而使用泛型则可以在存取对象时明确指名对象的类型,将问题暴露在编译阶段,由编译器检测,从而避免Java在运行时出现转型异常,增加程序的可读性与稳定性,提高程序的运行效率。
下面将通过实例阐述传统方法与Java泛型各自的使用方法与特点,并可以将这里介绍的泛型使用方法直接用于各种实际应用。
一、传统方法的弊端
在Java编程中,经常遇到众多对象的存取情况,比如在一个新闻系统中(假定新闻类为News),当从数据库中(即模型层)查询到某些新闻时,首先进行对象关系映射,也就是将每条新闻记录转变为一个News对象,然后再将News对象放入一个容器,在视图层显示时,从容器中将他们(News对象)一一取出,然后在视图层予以显示。
这个过程中,传统的处理方法是首先将News类作为Object类放入相应容器,读取时在再将容器中的每个对象(此时为Object类型)转型为对应的News类,然后进行相应的处理。
为了简单起见,我们用下面的代码来模拟上述过程。
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map m=new HashMap();
m.put(new Integer(1), new News("news1"));
m.put(new Integer(2), new String("news2"));
int i=0;
while(i News s=(News) m.get(new Integer(i+1));
System.out.println(s);
i++;
}
}
}
class News {
String title;
public News(String title){
this.title=title;
}
public String toString(){
return title;
}
}
上述的处理过程很明了,但实际上隐含了一个错误,在程序的输出语句中,为了使用News类的方法,需要将对象强制转型为News类型,这个转型在编译阶段不会出现任何问题,但在运行时,却抛出ClassCastException转型异常,从而造成程序的异常终止。另外此程序的可读性也不好,因为我们在使用map容器取对象时,根本不知道其中存放的是什么对象。
在JDK1.4之前,在处理相似的问题时,别无他法,只能这样来处理,至于运行时异常,只能靠我们写程序时小心。
二、利用泛型解决上述问题
Java的泛型就是在定义的同时明确指名其类型,增强程序的可读性。同时类型的检查在编译阶段就可以完成,避免运行时的异常,从而使程序有更强的健壮性。
泛型的定义形式为:class Java_Generics<K,V>,这里边的K和V就像方法中的参数一样,代表类型。
在Java的类库中,使用变量E表示集合的元素类型,K和V分别表示关键字与值的类型。T(需要时还可以用临近的字母U和S)可以表示任意类型。
现在利用泛型来重写Test类中的main函数的部分关键代码,News类不变,更改如下:
Map m=new HashMap();
m.put(new Integer(1), new News("news1"));
M.put(new Integer(2), new News("news2"));
// m.put(new Integer(3), new String("news3"));
int i=0;
while(i News s= m.get(new Integer(i+1));
System.out.println(s);
i++;
}
这段代码必须在JDK1.5或更高的版本上才能正确编译,注释掉的那行代码就是前面出现ClassCastException错误的原因。之所以被注释掉,是因为他在编译阶段就被发现了问题,必须做相应更改才能通过编译,提高了程序的健壮性。另外,当我们看到Map的定义的时候,很清楚能向Map中放入什么类型的对象,程序的可读性也大大增强。
基于上述示例的泛型应用在Java编程中的应用极为广泛,但都可以利用上述示例来方便的解决问题。在实际应用中,从容器中读出所有元素时,也可以利用Iterator指定。比如在一个List
容器中,把List转换为Iterator:Iterator it = list.iterator();这是可以使用泛型的另外一个地方。
三、泛型使用应注意的问题
究竟什么类可以指定特定的对象,使用泛型呢?最简单有效的方法是查阅JDK的API帮助文档,凡是后面有或等尖括号的,就可以指定明确的类型
另外,在使用泛型编程时还要注意以下几点:
(1)不可以用一个基本类型(如int float)来替换泛型。
(2)泛型类不可以继承Exception类。
(3)不可以定义泛型数组。
(4)不可以用泛型构造对象,即:News news = new T(); 是错误的。
(5)在static方法中不可以使用泛型,泛型变量也不可以用static关键字来修饰。
总之,在 Java 语言中使用泛型,会大大增强程序的易读性和健壮性,把隐含错误消除在编译阶段。学习如何使用泛型类型相当简单,但是同样也需要防范一些可能出现的错误。
参考文献:
[1](美)Cay S.Horstmann,Gary Cornell,叶乃文等译.JAVA 2核心技术机械工业出版社,2006.
[2](美)埃克尔著,陈昊鹏译,Java编程思想(第4版) 机械工业出版社2007.6.
作者简介:
李 森(1980-),男,河南南阳,在职研究生,助理讲师,主要从事Java和计算机网络方面研究。
注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
[关键词]Java 泛型 转型
中图分类号:TP3文献标识码:A 文章编号:1671-7597 (2008) 0210022-02
Java中的泛型是JDK1.5的新特性,在1.5及以后的版本中被支持。在Java编程中,常常用到在容器中存放对象或从容器中取出对象,并根据实际情况转型为相应的对象,但在转型过程中极易出现错误,且很难发现。而使用泛型则可以在存取对象时明确指名对象的类型,将问题暴露在编译阶段,由编译器检测,从而避免Java在运行时出现转型异常,增加程序的可读性与稳定性,提高程序的运行效率。
下面将通过实例阐述传统方法与Java泛型各自的使用方法与特点,并可以将这里介绍的泛型使用方法直接用于各种实际应用。
一、传统方法的弊端
在Java编程中,经常遇到众多对象的存取情况,比如在一个新闻系统中(假定新闻类为News),当从数据库中(即模型层)查询到某些新闻时,首先进行对象关系映射,也就是将每条新闻记录转变为一个News对象,然后再将News对象放入一个容器,在视图层显示时,从容器中将他们(News对象)一一取出,然后在视图层予以显示。
这个过程中,传统的处理方法是首先将News类作为Object类放入相应容器,读取时在再将容器中的每个对象(此时为Object类型)转型为对应的News类,然后进行相应的处理。
为了简单起见,我们用下面的代码来模拟上述过程。
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map m=new HashMap();
m.put(new Integer(1), new News("news1"));
m.put(new Integer(2), new String("news2"));
int i=0;
while(i
System.out.println(s);
i++;
}
}
}
class News {
String title;
public News(String title){
this.title=title;
}
public String toString(){
return title;
}
}
上述的处理过程很明了,但实际上隐含了一个错误,在程序的输出语句中,为了使用News类的方法,需要将对象强制转型为News类型,这个转型在编译阶段不会出现任何问题,但在运行时,却抛出ClassCastException转型异常,从而造成程序的异常终止。另外此程序的可读性也不好,因为我们在使用map容器取对象时,根本不知道其中存放的是什么对象。
在JDK1.4之前,在处理相似的问题时,别无他法,只能这样来处理,至于运行时异常,只能靠我们写程序时小心。
二、利用泛型解决上述问题
Java的泛型就是在定义的同时明确指名其类型,增强程序的可读性。同时类型的检查在编译阶段就可以完成,避免运行时的异常,从而使程序有更强的健壮性。
泛型的定义形式为:class Java_Generics<K,V>,这里边的K和V就像方法中的参数一样,代表类型。
在Java的类库中,使用变量E表示集合的元素类型,K和V分别表示关键字与值的类型。T(需要时还可以用临近的字母U和S)可以表示任意类型。
现在利用泛型来重写Test类中的main函数的部分关键代码,News类不变,更改如下:
Map
m.put(new Integer(1), new News("news1"));
M.put(new Integer(2), new News("news2"));
// m.put(new Integer(3), new String("news3"));
int i=0;
while(i
System.out.println(s);
i++;
}
这段代码必须在JDK1.5或更高的版本上才能正确编译,注释掉的那行代码就是前面出现ClassCastException错误的原因。之所以被注释掉,是因为他在编译阶段就被发现了问题,必须做相应更改才能通过编译,提高了程序的健壮性。另外,当我们看到Map的定义的时候,很清楚能向Map中放入什么类型的对象,程序的可读性也大大增强。
基于上述示例的泛型应用在Java编程中的应用极为广泛,但都可以利用上述示例来方便的解决问题。在实际应用中,从容器中读出所有元素时,也可以利用Iterator指定。比如在一个List
容器中,把List转换为Iterator:Iterator
三、泛型使用应注意的问题
究竟什么类可以指定特定的对象,使用泛型呢?最简单有效的方法是查阅JDK的API帮助文档,凡是后面有
另外,在使用泛型编程时还要注意以下几点:
(1)不可以用一个基本类型(如int float)来替换泛型。
(2)泛型类不可以继承Exception类。
(3)不可以定义泛型数组。
(4)不可以用泛型构造对象,即:News news = new T(); 是错误的。
(5)在static方法中不可以使用泛型,泛型变量也不可以用static关键字来修饰。
总之,在 Java 语言中使用泛型,会大大增强程序的易读性和健壮性,把隐含错误消除在编译阶段。学习如何使用泛型类型相当简单,但是同样也需要防范一些可能出现的错误。
参考文献:
[1](美)Cay S.Horstmann,Gary Cornell,叶乃文等译.JAVA 2核心技术机械工业出版社,2006.
[2](美)埃克尔著,陈昊鹏译,Java编程思想(第4版) 机械工业出版社2007.6.
作者简介:
李 森(1980-),男,河南南阳,在职研究生,助理讲师,主要从事Java和计算机网络方面研究。
注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。