admin 管理员组文章数量: 1184232
2024年1月16日发(作者:c程序设计第五版谭浩强pdf百度云)
第25卷第3期 电脑开发与应用 (总223) ・63・ 文章编号:1003—585O(2O12)O3一OO63—03 Java泛型研究 林帅 ,林雄。 (1.四川大学软件学院,成都610207,2.琼州大学电子信息工程学院,海南三亚572022) 摘 要:2004年2月,Sun公司(2010年1O月已被Oracle收购)在它发布的J2SE1.5版中加入了泛型,允许对类型进行抽象, 程序员只需声明一个接受可变数目参数的方法,便可得到强类型在编译时刻进行类型检查的好处,简化了程序的开发。阐述了泛型 基本概念和作用,介绍了在Java类、接12:和方法中使用泛型的方法,通过实例比较使用泛型和不使用泛型的区别,最后指出使用泛 型时要注意的问题。 关键词;J2SE1.5,泛型,类型参数 中图分类号:TP31 文献标识码:A Research on Java Generics LIN Shuai ,LIN Xiong (1.College oj Software Engineering,Sichuan University,Chengdu 610207,China, 2.College ofElectronic and Information Engineeirng。Qiongzhou University,Sanya 572022,China) Abstract:In February 2004,Sun released Java 2 SDK,Standard Edition Version 1.5.0 Beta 1,added generic versions allowing abstract over types.Programmers simply define a method that accepts a variable number of arguments,then they can get benefits of type checking which simplifies program development.This article describes the basic concepts and the role of Java generics,introduces how to make use of Java generics in Java classes,Java interfaces,and Java methods,tells the difference between using Java generics programming and not using by examples.At the last,some problems which need pay attention to in the use of Java generics are summarized. Key words:J2SE1.5,java generics,type parameter Java集合(Collection)中元素的类型是多种多样 问题,J2SE 1.5引入泛型也是自然而然的了。 的。例如,有些集合中的元素是Byte类型的,而有些则 可能是String类型的,等等。Java允许程序员构建一 1 什么是Java泛型 个元素类型为Object的Collection,其中的元素可以 泛型[ 是J2SE1.5中引入的一个新特性,其本质 是任何类型。在Java SE 1.5之前,没有泛型 是参数化类型,也就是说所操作的数据类型被指定为 (Generics)的情况下,通过对类型Object的引用来实 一个参数(type parameter)。这种参数类型可以用在 现参数的“任意化”,“任意化”带来的缺点是要作显式 类、接口和方法的创建中,分别称为泛型类、泛型接I:1、 的强制类型转换,而这种转换是要求开发者对实际参 泛型方法。先看下面的代码: 数类型可以在预知的情况下进行的。对于强制类型转 List<Integer>list=new ArrayList<Integer>()} 换错误的情况,编译器可能不提示错误,在运行的时候 Integer IlUlTI=list.get(O)l 才出现异常,这是一个安全隐患。因此,为了解决这一 这里,list是一个装有Integer对象的list。get方 法返回一个Integer对象实例,这个过程不需要进行 * 收稿日期:2011—11—13,修回日期:2012-01—20 ** 基金项目;三亚市院校专项资金项目资助课题(YD09069) ***林帅,男,1991年生,研究方向:计算机软件。
Java泛型研究 类型转换。如果没有泛型,则上面的代码需写成: List list=new ArrayList(); Integer hum。(Integer)list.get(0); 但是,如果程序员曾经把一个非Integer对象加 入list中,上面的代码会抛出一个 ClassCastException。有了泛型,程序员就可以创建一 个单一用途的List实例。例如,创建一个只接受 Integer对象的List实例,另外一个实例只能接受 String对象。可见,泛型的主要好处就是让编译器保留 参数的类型信息,执行类型检查,执行类型转换操作; 编译器保证了这些类型转换的绝对无误。 相对于依赖程序员来记住对象类型、执行类型转 换——这会导致程序运行时的失败,很难调试和解决, 而编译器能够帮助程序员在编译时强制进行大量的类 型检查,发现其中的错误。 2 泛型的作用 第一是泛化。可以用丁代表任意类型。Java语言 中引人泛型是一个较大的功能增强。不仅语言、类型系 统和编译器有了较大的变化,以支持泛型,而且类库也 进行了大翻修,所以许多重要的类,比如集合框架,都 已经成为泛型化的了,这带来了很多好处。 第二是类型安全。泛型的一个主要目标就是提高 Java程序的类型安全,使用泛型可以使编译器知道变 量的类型限制,进而可以在更高程度上验证类型假设。 如果不用泛型,则必须使用强制类型转换,而强制类型 转换不安全,在运行期可能发生ClassCastException 异常,如果使用泛型,则会在编译期就能发现该错误。 第三是消除强制类型转换。泛型可以消除源代码 中的许多强制类型转换,这样可以使代码更加可读,并 减少出错的机会。 第四是向后兼容。支持泛型的Java编译器(例如 JDK1.5中的Javac)可以用来编译经过泛型扩充的 Java程序(Generics Java程序),但是现有的没有使用 泛型扩充的Java程序仍然可以用这些编译器来编译。 3 在JaVa类、接口和方法中使用泛型 3.1泛型类、泛型接口 如果定义的一个类或接口有一个或多个类型变 量,则可以使用泛型。泛型类型变量由尖括号界定,放 在类或接口名的后面,下面定义尖括号中的 称为类 型变量。意味着一个变量将被一个类型替代。替代类 型变量的值将被当作参数或返回类型。对于List接口 来说,当一个实例被创建以后,丁将被当作一个函数的 参数。下面分别是泛型类、泛型接口的定义: public class Gen<T>{//泛型类 ) public interface List<T>extends Collection<T> 泛型接口 } 可以说,类型变量扮演的角色就如同一个参数,它 提供给编译器用来类型检查的信息。Java类库里的很 多类,如Collection都作了泛型化的修改。在上面的第 一段代码里用到的List接口就是一个泛型接口。在那 段代码里,nLlm是一个List<Integer>对象,它是一 个带有Integer类型变量的List接口的类实现的实 例。编译器使用这个类型变量参数在get方法被调用、 返回一个Integer对象时自动对其进行类型转换。 3.2泛型方法 是否拥有泛型方法,与其所在的类是否泛型无关。 要定义泛型方法,只需将泛型参数列表置于返回值前。 如: public class ExampleA( public<T>void f(T x)( System.OUt.println(x.getClass().getName())I ) public static void main(String args[])f ExampleA ea=new ExampleA()l ea.f(””)‘ ea.f(1O); ea.f(’a’); ea.f(ea); ) ) 使用泛型方法时,不必指明参数类型,编译器会自 己找出具体的类型。泛型方法除了定义不同,调用就像 普通方法一样。 需要注意,一个static方法,无法访问泛型类的类 型参数,所以,若要static方法需要使用泛型能力,必 须使其成为泛型方法。 4 泛型和非泛型的比较 下面两个例子嘲实现同样的功能,一个使用了泛 型,一个没有使用。 例子一:使用泛型 public class Gen<T>{ private T ob;//定义泛型成员变量 public Gen(T ob){ this.ob=ob1 )
第25卷第3期 电脑开发与应用 (总225) ・65・ public T getObO{ return ob} } public void setOb(T ob){ this.ob=ob; ) public void showTyep 0{ System.out.println(”T的实际类型是:”+ ob.getClassO.getName())l ) ) public ClaSS GenDemo{ public static void main(String[]args){ //定义泛型类Gen的一个Integer版本 Gen<Integer>intOb=new Gen<Integer>(88); intOb.showTyep O; int i---intOb.getObO, System.out.println(”value== +i); System.out.println(” //定义泛型类Gen的一个String版本 Gen<String>strOb=new Gen<string>(”Hello Gen! ); strOb.showTyep()} String s=strOb.getOb(); System.out.println( value:=”+s); ) ) 例子二:没有使用泛型 public class Gen2{ private Object ob;//定义一个通用类型成员 public Gen2(Object ob){ this.ob—ob; ) public Object getOb O{ return ob; ) public void setOb(Object ob)( this.ob=ob1 ) public void showTyep O{ System.Out.println(”T的实际类型是: + ob.getClassO.getName()); } ) public class GenDemo2{ public static void main(String[]args){ //定义类Gen2的一个Integer版本 Gen2 intOb—new Gen2(new Integer(88)); intOb.showTyep(); int i=(Integer)intOb.getOb(), System.out.println( values +i); System.out.println(”…---……… ); //定义类Gen2的一个String版本 Gen2 strOb=new Gen2("Hello Gen!”); strOb.showTyep(); String S=(String)strOb.getOb O; System.OUt.println(”value=”+s); } ) 这两个例子运行结果都是相同的,在控制台输出 结果如下: T的实际类型是:java.1ang.Integer value=88 T的实际类型是:java.1ang.String value Hello Gen! 通过比较以上两个例子,就基本掌握Java泛型的 应用。 5 使用泛型要注意的问题 使用Java泛型应该注意如下几点: ①在定义一个泛型类时,在“<>”之间定义形式 类型参数,例如:“class TestGen ̄K,V>”,其中“K” ,“V”不代表值,而是表示类型。 ②实例化泛型对象时,一定要在类名后面指定类 型参数的值(类型),一共要有两次书写。例如: TestGen ̄String,String ̄ t---new TestGen<String,String ̄O; ③泛型中<K extends Object ̄,extends并不代 表继承,它是类型范围限制。 ④使用泛型时,泛型类型必须为引用数据类型,不 能为基本数据类型,Java中的普通方法,构造方法,静 态方法中都可以使用泛型,方法使用泛型之前必须先 对泛型进行声明,可以使用任意字母,一般都要大写。 ⑤不可以用一个本地类型(如int、float)来替换泛 型。 ⑥运行时类型检查,不同类型的泛型类是等价的 (Pair与Pair是属于同一个类型Pair),这一点要特别 注意,即如果obj instance of Pair一一true的话,并不 代表obj.getFirst()的返回值是一个String类型。 ⑦泛型类不可以继承Exception类,即泛型类不 可以作为异常被抛出。 ⑧不可以定义泛型数组。 ⑨不可以用泛型构造对象,即:first—new T(); 是错误的。 (下转第68页)
以十进制为中心的进制转换算法的设计与实现 ②调用StringToTen(),判断Flag的值和字符串 的长度。 ③将字符串”1A”中字符’1’转换成十进制1存放 在数组的第1个位置,将字符’A’转换成十进制10存 放在数组的第2个位置,此时的数组的长度为2,所以 将字符串转换成十进制数字,再将十进制数字转换成 其他进制,并用程序将之实现。提出了字符串转换成十 进制数算法和十进制数转换成其他进制数算法,该算 法通用性较强,转换速度快,有较好的实用性,对进制 转换器和多功能计算器的设计和开发有一定的参考价 值。 第1个数的位权就是基数的1次方(2—1—0—1),第2 个数的位权为基数的0次方(2-1-1=O),所以1×16 +1O×16。一26,这样就将十六进制字符串“1A”转换 成十进制数字26。 参考文献: [1] 严蔚敏,吴伟民.数据结构(C语言版)[M].北京:清华 大学出版社,1997;44—54. ④调用函数TenToOther(),通过取基取余法得 到余数3和2,将3和3保存在数组中返回到主调函 数OnRADIOEight()并输出到转换器界面。结果如图 5所示。 [2] 潘爱民,王国印.VC++技术内幕(第4版)[M].北 京:清华大学出版社,2009:64—88. [3] 钱[4] 王能.C++程序设计教程[M1.北京:清华大学出版 磊,希雷,王健.数制转换口].计算机工程与 社,2005:252-288. 应用,2003(32):95—97,100. [5] 刘建波,蔡文水,吕铁山.十进制与任意进制转换的设 图5十六进制数1A转换成八进制32 计与实现口].计算机系统应用,2003(10);69—71. [6] 陈清华,郑涛,陈家伟.数制转换的本质和方法口]. 江西师范大学学报(自然科学版),2006,30(2):123— 126. 4 结束语 在VC++6.0平台下,利用MFC实现常用进制 之间的转换,提出以十进制为转换中心的转换算法,先 [7] 王迎春,吉利久.一种基于简单移位的二一十进制相互 转换算法口].电子学报,2003(2)t 221—224. (上接第65页) to run the OSGi②framework 1.2),这一平台并不支 持Java泛型。因此,在JRE(Java Runtime ⑩在static方法中不可以使用泛型,泛型变量也 不可以用static关键字来修饰。 ⑨不要在泛型类中定义equals(T x)这类方法, 因为Object类中也有equals方法,当泛型类被擦除 后,这两个方法会冲突。 ③根据同一个泛型类衍生出来的多个类之间没有 任何关系,不可以互相赋值,即: Pair plf Pair p2;pl=p2;这种赋值是错误的。 Environment)选项中就应该选择J2SE一1.5或 JavaSE一1.6,否则,凡使用泛型的代码段的地方都会出 现红色标记(不符合语法),这一点是初学者要特别注 意的。 6 结束语 J2SE1.5在易用性上作了重大改进,引入了泛型、 增强for循环、元数据、类似C语言的格式化输入输 ⑩若某个泛型类还有同名的非泛型类,不要混合 使用,坚持使用泛型类。 Pair<Manager>managerBuddies = new Pair< 出、静态导入、可变参数等。但使用泛型类型需要避免 一些错误隐患,以提高程序的健壮性。 Manager>(ceo,efo)I Pair rawBuddies—managerBuddies; 参考文献: [1] 叶核亚.Java2程序设计实用教程(第2版)[M].北 京:电子工业出版社,2007. 这里编译器不会报错,但存在着严重的运行错误 隐患。 此外,由于Eclipse 2010中在工作区间 (workspace)中创建一个Java项目(Project)时,默认 使用的执行环境(Use an execution environment JRE) 是OSGi/Minimum一1.2(OSGi Minimum environment [2] 熔 岩.Java泛型的理解与等价实现[J/OL]. http://lavasoft.blog.51cto.com/62575/42400,2007— 09。O8.
版权声明:本文标题:Java泛型研究 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1705358319a482503.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论