JAVA5新特性介绍.doc_第1页
JAVA5新特性介绍.doc_第2页
JAVA5新特性介绍.doc_第3页
JAVA5新特性介绍.doc_第4页
JAVA5新特性介绍.doc_第5页
免费预览已结束,剩余51页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

WoyoJAVA5新特性介绍DOC第 56 页 共 56 页JAVA5新特性介绍修改记录目 录21. OverViewJAVA编程语言发展到5.0版本,出现了很多和之前JAVA版本相比比较新颖的特性。从另一方面来看,没有自动进化符合时代发展的语言(包括人类使用的各种自然语言)都将被淘汰。因此学习JAVA编程语言也要紧跟时代,争取让身为JAVA程序员的自己不会沦为被淘汰的那群程序员中。本文主要针对这些新颖的特性结合实际代码示例进行介绍。学习这些新特性,并运用到实际编程工作中去是撰写本文的最终目的。2. 特性一览2.1Collection中一些新的类和方法2.1.1 java.util.Arrays代码:package com.woyo.collection;import java.util.Arrays;public class ArraysTester private int ar;public ArraysTester(int numValues) ar = new intnumValues;for (int i = 0; i ar.length; i+) ari = 700 - i;public int get() return ar;public static void main(String args) ArraysTester tester = new ArraysTester(50);int myArray = tester.get();/compare two arraysint myOtherArray = tester.get().clone();if (Arrays.equals(myArray, myOtherArray) System.out.println(the two arrays are equal); else System.out.println(the two arrays are not equal);/inster some elementsArrays.fill(myArray, 2, 10, new Double(Math.PI).intValue();myArray30 = 98;/print array nowSystem.out.println(Here is unsorted array.);System.out.println(Arrays.toString(myArray);System.out.println();/sort arrayArrays.sort(myArray);/print sorted arraySystem.out.println(Here is sorted array.);System.out.println(Arrays.toString(myArray);System.out.println();/get index of valueint index = Arrays.binarySearch(myArray, 98);System.out.println(98 is located in the array at index + index);String ticTacToe = X, O, O , O, X, X , X, O, X ;System.out.println(Arrays.deepToString(ticTacToe);String ticTacToe2 = O, X, X , O, X, X , X, O, X ;String ticTacToe3 = X, O, O , O, X, X , X, O, X ;if (Arrays.deepEquals(ticTacToe, ticTacToe2) System.out.println(bords 1 and 2 are equal); else System.out.println(bords 1 and 2 are not equal);if (Arrays.deepEquals(ticTacToe, ticTacToe3) System.out.println(bords 1 and 3 are equal); else System.out.println(bords 1 and 3 are not equal);这段代码向我们演示了在java中的java.util.Arrays这个类,它提供了一些新的静态方法。以下一一做接扫:1. toString方法。使用这个方法可以帮助你打印出array的所有元素。2. deepToString方法。这个方法是帮助你打印出多维array的所有内容。3. deepEquals方法,这个方式是帮助你比较多维array的内容的。请运行上述代码,在控制台中仔细查看输出结果。另外还有hashCode和deepHashCode方法也是新增的静态方法。至于具体用途和上述方法类似,可以编写测试代码自己来感受一下。2.1.2 java.util.Queue代码:package com.woyo.collection;import java.io.IOException;import java.io.PrintStream;import java.util.LinkedList;import java.util.Queue;public class QueueTester public Queue q;public QueueTester() q = new LinkedList();public void testFIFO(PrintStream out) throws IOException q.offer(First);q.offer(Second);q.offer(Third);Object o;while (o = q.poll() != null) out.println(o);public static void main(String args) QueueTester tester = new QueueTester();try tester.testFIFO(System.out); catch (Exception e) e.printStackTrace();在testFIFO方法中,可以知道queue是按照先进先出(FIFO)的方式存储数据的。所以第一个进queue的元素是第一个出来的。你还可以由上面代码可知queue接口可以用LinkedList类来实现。如果不想以queue缺省的排序方式来排序,可以使用queue的另外一种实现类PriorityQueue。当然你要给这个类一个Comparator来实现。相关代码可见如下:package com.woyo.collection;import java.util.Comparator;import java.util.PriorityQueue;public class PriorityQueueTester public static void main(String args) PriorityQueue pq = new PriorityQueue(20, new Comparator() public int compare(Integer i, Integer j) int result = i % 2 - j % 2;if (result = 0) result = i - j;return result;);for (int i = 0; i 20; i+) pq.offer(20 - i);for (int i = 0; i 20; i+) System.out.println(pq.poll();运行该段程序,结果输出如下图:由此可以明白PriorityQueue并没有按照FIFO方式对元素进行排序,而是根据定义的排序方式先从低到高输出偶数,然后从低到高输出奇数。2.1.3 Override返回类型在JAVA5中对于override的方法可以override返回类型,前提是子类的override的方法返回的对象必须是父类被override的方法返回对象的子类。可以见如下代码:Point2D:package com.woyo.collection;public class Point2D protected int x, y;public Point2D() this.x = 0;this.y = 0;public Point2D(int x, int y) this.x = x;this.y = y;Point3D:package com.woyo.collection;public class Point3D extends Point2D protected int z;public Point3D(int x, int y) this(x, y, 0);public Point3D(int x, int y, int z) this.x = x;this.y = y;this.z = z;Position2D:package com.woyo.collection;public class Position2D Point2D location;public Position2D() this.location = new Point2D();public Position2D(int x, int y) this.location = new Point2D(x, y);public Point2D getLocation() return location;Position3D:package com.woyo.collection;public class Position3D extends Position2D Point3D location;public Position3D(int x, int y, int z) this.location = new Point3D(x, y, z);public Point3D getLocation() return location;可以由Position3D类中getLocation方法看出来子类Position3D的返回类型对象是Point3D。它恰恰是父类Position2D的getLocation方法返回的对象Point2D的子类。这就符合之前所述的override返回类型的条件。我们又将此称之为“协变返回”。2.1.4 StringBuilderStringBuilder这个类其实和StringBuffer的使用方式是相同的。只是StringBuilder在确定线程安全性不是问题的情况下用来替换StringBuffer。也就是说如果你是在单线程环境或者不担心会有太多的线程访问,或者是同步机制的情况下,完全可以用StringBuilder来代替StringBuffer。下面是一段示例代码,使用StringBuffer来编写程序,然后全部替换成StringBuilder。package com.woyo.collection;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class StringBuilderTester public static String appendItems(List list) StringBuilder b = new StringBuilder();for (Iterator i = list.iterator(); i.hasNext();) b.append(i.next().append( );return b.toString();public static void main(String args) List list = new ArrayList();list.add(I);list.add(play);list.add(Bourgeois);list.add(guitars);list.add(and);list.add(Huber);list.add(banjos);System.out.println(StringBuilderTester.appendItems(list);2.2 泛型可以说泛型是JAVA5中引入的新特性中最重要的特性。它是其他新特性的基础,比如可变参数,注解,枚举和上文所述的collection。因此要花更多的时间和精力来学习一下。2.2.1 创建类型安全的list我们在使用java5之前的java版本语言进行开发的时候,在list中添加了一个已知类型的对象,但是在取出这个对象时候还要进行强制类型转化。如果你不这样做,编译就会报错。现在使用java5就可以利用泛型的限制来制定List中的元素类型。如以下代码:List listOfString;List listOfString= new ArrayList();也就是说在listOfString这个list中你只能添加String类型的元素进去。而不能是其他类型。但是有一点要注意的是尖括号中容许的类型是对象,因此像int这种类型是不会编译的。因为它们不接受primitive value。2.2.2 创建类型安全的Map和list一样,java5中的map也是被泛型所支持。如以下代码可见:public void testTypeSafeMaps(PrintStream out) throws IOException Map squares = new HashMap();for (int i = 0; i 100; i+) squares.put(i, i * i);for (int i = 0; i 10; i+) int n = i * 3;out.println(The square of + n + is + squares.get(n);因为Map对象是由key-value来组成的,因此新建一个Map对象时候要用泛型申明它的key和value类型。2.2.3 在遍历中使用参数化类型对象如果新建了一个集合对象,将此对象转化成一个Iterator对象进行遍历的时候要注意一件事情,请看下列代码,注意黑体部分。public void testTypeSafeIterators(PrintStream out) throws IOException List listOfStrings = new LinkedList();listOfStrings.add(Happy);listOfStrings.add(Birthday);listOfStrings.add(To);listOfStrings.add(You);for (Iterator i = listOfStrings.iterator(); i.hasNext();) String s = i.next();out.println(s);printListOfStrings(getListOfStrings(), out);其实我们要注意的就是如果我们新建一个被参数化的集合对象,则在使用Iterator对象时候也要使用相同的参数。在上述代码中listOfStrings集合对象的参数是String,则Iterator对象的参数也要是String。否则进行listOfStrings.iterator()转化时候Iterator对象中的元素会是Object而不是String,这样就会编译错误。2.2.4 参数化类型对象作为方法参数可以将被参数化的对象作为方法的参数传入,见如下代码private void printListOfStrings(List list, PrintStream out) throws IOException for (Iterator i = list.iterator(); i.hasNext();) out.println(i.next();这样在方法中就避免了类型转化的情况,编译时候知道List中的元素对象只能是String类型对象。同时Iterator对象也被参数化,遍历时候知道是遍历String类型对象元素。2.2.5 参数化类型对象作为方法返回类型在JAVA的方法中不仅可以将参数化类型的对象作为方法参数,也可以返回被参数化的类型对象。如下代码:private List getListOfStrings() List list = new LinkedList();list.add(Hello);list.add(World);list.add(How);list.add(Are);list.add(You?);return list;虽然把去掉,编译也能通过,但是getListOfStrings方法返回的对象如果被其他方法调用,则不知道是否是其中元素是String对象的集合了。在其他方法中就需要做类型校验了。2.2.6 参数化类型对象也可以作为类型参数拿Map作为例子,它的两个参数key和value。通常key会是String或者是Integer,而value可能是任何对象。当然也包括参数化类型对象,如可以使用List。请看以下代码:MapString,List map = new HashMapString, List();这里Map的value就是一个List类型的对象。2.2.7 使用通配符假设在你的代码中使用List和Map的集合对象时候必须要使用JAVA5之前版本的List,Map写法。但是又有使用了泛型的List,Map对象。这将会引发某些异常发生,尤其是类型转化的异常发生。这时候可以采用通配符。如以下代码示例public void printList(List list, PrintStream out) throws IOException for (Iterator i = list.iterator(); i.hasNext();) out.println(i.next().toString();这段代码使用了?来表示通配符运算符号,表明printList方法可以接受任何对象组成的List。同时按照前面所述,对Iterator对象进行遍历也需要使用?来表达。2.2.8 自定义泛型JAVA5中除了使用以上技术的泛型操作。它还允许开发者自定定义自己的泛型类型。如以下代码就是一个自定义泛型对象的示例。package com.woyo.generic;import java.util.ArrayList;import java.util.List;public class Box protected List contents;public Box() contents = new ArrayList();public int getSize() return contents.size();public boolean isEmpty() return (contents.size() = 0);public void add(T o) contents.add(o);public T grab() if (!isEmpty() return contents.remove(0); elsereturn null;以上代码中的字母T就是用来代表一个类型参数。这样你就可以使用任何对象来填充这个T,比如你新建一个上面代码中的BOX对象。可以这么写Box box = new Box();值得说一句的是泛型对象不能静态变量但可以在静态方法中作为方法参数使用。如:private static List staticList = new ArrayList();/这个是非法的/这个是合法的public static int biggest(Box box1,Box box2)int box1Size = box1.getSize();int box2Size = box2.getSize();return Math.max(box1Size,box2Size);2.2.9 限制类型参数还是以上面的Box对象为例。如果你希望Box对象中的元素是只接受数值的,而不是其他对象,则可以像下面这么写代码:package com.woyo.generic;import java.util.Iterator;public class NumberBox extends Box public NumberBox() super();/ Sum everything in the boxpublic double sum() double total = 0;for (Iterator i = contents.iterator(); i.hasNext();) total = total + i.next().doubleValue();return total;public static double sum(Box box1, Box box2) double total = 0;for (Iterator i = box1.contents.iterator(); i.hasNext();) total = total + i.next().doubleValue();for (Iterator i = box2.contents.iterator(); i.hasNext();) total = total + i.next().doubleValue();return total;这样子就规定了Box对象中的元素对象只能是Number类的子类或者就是Number类。所以如果new一个Box对象实例不能写成NumberBox a = new NumberBox();/因为String不是Number类的子类当然在上面代码中也可知在方法中也可以使用相同的手法。请阅读最后一个sum方法。2.3 枚举在java5之前版本对于仅容许特定数据类型值集合的对象定义也是使用枚举的,但是它有很大的不足之处,因此在JAVA5中对枚举又重新做了定义和修改。因此有必要对枚举的新特性和使用方式做学习。2.3.1 创建枚举创建一个枚举类型一般要使用enum关键字,命名类型名称,定义类型所允许的各个值。可参考以下代码:package com.woyo.enumerated;public enum Grade A, B, C, D, F, INCOMPLETE;然后可以用一个类来使用这个Grade枚举类。值得注意的是枚举类中的元素都要用大写字母来表示。使用Grade的代码如下:package com.woyo.enumerated;public class Student private String firstName;private String lastName;private Grade grade;public Student(String firstName, String lastName) this.firstName = firstName;this.lastName = lastName;public void setFirstName(String firstName) this.firstName = firstName;public String getFirstName() return firstName;public void setLastName(String lastName) this.lastName = lastName;public String getLastName() return lastName;public String getFullName() return new StringBuffer(firstName).append( ).append(lastName).toString();public void assignGrade(Grade grade) this.grade = grade;public Grade getGrade() return grade;2.3.2 遍历枚举每一个枚举类型对象其实都内置了一个叫values的方法。这个方法提供对枚举类型中所有定义的值的访问。如下代码:public void listGradeValues(PrintStream out) throws IOException Grade gradeValues = Grade.values();/ for loopfor (int i = 0; i gradeValues.length; i+) out.println(Allowed value: + gradeValuesi + );/ for/in loopfor (Grade g : gradeValues) out.println(Allowed value: + g + );由代码可知values方法返回一个数组对象,这个数组对象中的每个元素都是一个grade枚举对象在out.pringln方法中每个grade枚举对象都在执行自己的toString方法,打印自己的值的String名称。当然也可以使用for/in循环(我们之后也会提到这种循环)来同样的打印出每一个grade枚举对象的值。2.3.3 Switch中使用枚举我们以前就知道在java中switch仅能判断int,short,char和byte值。但是java5中海允许使用枚举类型的值。如以下代码所示:public void testSwitchStatement(PrintStream out) throws IOException StringBuffer outputText = new StringBuffer(student1.getFullName();switch (student1.getGrade() case A:outputText.append( excelled with a grade of A);break;case B: / fall through to Ccase C:outputText.append( passed with a grade of ).append(student1.getGrade().toString();break;case D: / fall through to Fcase F:outputText.append( failed with a grade of ).append(student1.getGrade().toString();break;case INCOMPLETE:outputText.append( did not complete the class.);break;default:outputText.append( has a grade of ).append(student1.getGrade().toString();break;out.println(outputText.toString();指的注意的是一定要列出所有grade枚举类中定义的值的处理情况。如果不想对所有值的情况进行处理,则可以像上面代码,将不处理的情况让default来处理。2.3.4 Java.util.EnumMap我们可以使用EnumMap这个类来定义使用枚举作为key的map对象。代码如下:AntStatus类:package com.woyo.enumerated;public enum AntStatus INITIALIZING, COMPILING, COPYING, JARRING, ZIPPING, DONE, ERRORAntStatusTester类package com.woyo.enumerated;import java.io.IOException;import java.io.PrintStream;import java.util.EnumMap;public class AntStatusTester public AntStatusTester() public void testEnumMap(PrintStream out) throws IOException / Create a map with the key and a String messageEnumMap antMessages = new EnumMap(AntStatus.class);/ Initialize the mapantMessages.put(AntStatus.INITIALIZING, Initializing Ant.);antMessages.put(AntStatus.COMPILING, Compiling Java classes.);antMessages.put(AntStatus.COPYING, Copying files.);antMessages.put(AntStatus.JARRING, JARring up files.);antMessages.put(AntStatus.ZIPPING, ZIPping up files.);antMessages.put(AntStatus.DONE, Build complete.);antMessages.put(AntStatus.ERROR, Error occurred.);/ Iterate and print messagesfor (AntStatus status : AntStatus.values() out.println(For status + status + , message is: + antMessages.get(status);public static void main(String args) try AntStatusTester tester = new AntStatusTester();tester.testEnumMap(System.out); catch (IOException e) e.printStackTrace();毕竟map中的元素是无序排列的。如果使用EnumMap我们就可以确保不会弄乱顺序来赋值。还有既然有了新的EnumMap,那么肯定也有EnumSet这个类。它们都是java5中新增加的集合类。2.4 自动装箱与拆箱当我们学习java的时候,就知道在java中像int,short,char都属于primitive类型。而还有一种wrapper类型的类,即Integer,Short,Character。我们有时候要在这两者之间进行类型转化。这样子代码就会变得很繁琐和不可控制。现在java5中提供了两个新的转化功能来处理primitive和wrapper之间的转换。这就是autoboxing和auto-unboxing。2.4.1 Primitive类型转化为Wrapper类型这样的类型转化很简单,如下代码:/ Boxingint foo = 0;Integer integer = foo;2.4.2 Wrapper类型转化为Primitive类型同理,可见以下代码:Integer counter = 1; / boxingint counter2 = counter; / unboxing2.4.3 Wrapper类型的递增和递减有前面两段代码可知,现在primitive和wrapper类型可以互相转化,那么对primitive类型的操作肯定可以用来操作wrapper类型。比如+和- -这两个操作就可以用于wrapper类型。如下代码:Integer counter = 1; / boxingwhile (true) System.out.printf(Iteration %d%n, counter+);if (counter 1000)break;2.4.4 Boolean和boolean这两个类型之间的转化比较特殊,因为很多!,| ,&这种与或非的操作符都和这两个有关,现在这些操作符也可以使用在Boolean的值上。如以下代码:Boolean case1 = true;Boolean case2 = true;boolean case3 = false;Boolean result = (case1 | case2) & case3;2.4.5 三元表达式和拆箱同之前一样,三元表达式中也对Boolean类型进行了支持,这在java5之前版本,三元表达式所返回的类型一定要是boolean,现在Boolean也可以了。如以下代码:Boolean arriving = false;Boolean late = true;System.out.println(arriving ? (late ? Its about time! : Hello!) : (late ? Better hurry! : Goodbye);2.4.6 流程控制语句和拆箱类似的在流程控制语句中也是如此,在需要判断boolean值的时候,也可以采用Boolean值,另外switch语句中除了前面所述接受枚举类型之外,也接受Integer,Short,Char,Byte值。示例代码如下:Boolean arriving = false;Integer peopleInRoom = 0;int maxCapacity = 100;boolean timeToLeave = false;while (peopleInRoom 0);2.5 可变参数当你为某个类设置多个构造方法时候,有可能其中会有多个方法参数。但是如果程序要扩展新功能,需要再增加几个方法参数时候,则不得不新增几个构造方法。在java5中则不必这样做就能达到程序扩展的要求。这里就是利用可变参数特性来解决。2.5.1 创建可变参数列表创建可变参数列表非常简单,只需要习惯输入“”就可以了。请看如下代码示例:package com.woyo.vararg;import java.util.List;public class Guitar private String builder;private String model;private float nutWidth;private GuitarWood backSidesWood;private GuitarWood topWood;private GuitarInlay fretboardInlay;private GuitarInlay topInlay;private List features;private static final float DEFAULT_NUT_WIDTH = 1.6875f;public Guitar(String builder, String model, String. features) this(builder, model, null, null, DEFAULT_NUT_WIDTH, null, null, features);public Guitar(String builder, String model, GuitarWood backSidesWood, GuitarWood topWood, float nutWidth,String. features) this(builder, model, backSidesWood, topWood, nutWidth, null, null, features);public Guitar(Strin

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论