J2SE 5.0新功能有什么?

J2SE 5.0新功能有什么?

1. Generic Types

5.0以前,当我们需要从集合类当中提取出某个元素时,需要显式的对他进行下塑造型,如

ArrayList list = new ArrayList();

list1.add(0, new Integer(42));

int total = ((Integer)list1.get(0)).intValue();

 

5.0当中,通过使用Generic Types,即将集合类(Collection)的声明写成Collection<E>,这样我们就可以在使用的时候不需要再进行显示的造型

ArrayList<Integer> list = new ArrayList<Integer>();

list.add(0, new Integer(42));

int total = list.get(0).intValue();

 

2. Autoboxing and Auto-Unboxing of Primitive Types

由于集合类(Collection)里面只能保存从Object当中继承而来的对象,所以对于基本类型(Primitive Type)的变量,如intfloat等,在添加到Collection当中时,需要使用他们对应的封装类IntegerFloat等,如:

 ArrayList<Integer> list = new ArrayList<Integer>();
  list.add(0, new Integer(42)); 
 int total = (list.get(0)).intValue();

 

5.0当中,通过使用AutoboxingAuto-Unboxing我们就不再需要显式的使用这些封装类了。

 ArrayList<Integer> list = new ArrayList<Integer>();
 list.add(0, 42);
 int total = list.get(0);

 

3. Enhanced for Loop

一般来说,当我们需要对数组和集合进行遍历时,我们需要这样做:

 ArrayList<Integer> list = new ArrayList<Integer>();

list.add(0,1);

list.add(1,2);

 for (Iterator i = list.iterator(); i.hasNext();) {
  Integer value=(Integer)i.next();
 }

但使用了5.0Enhanced for Loop以后,我们的循环可以变得很简单:

ArrayList<Integer> list = new ArrayList<Integer>();

list.add(0,1);

list.add(1,2);

for(int i:list){

System.out.println(i);

}

 

同理,数组的遍历也从原来的:

int[] b = new int[3];

for(int i=0;i<b.length;i++){System.out.println(b[i]);}

变为:

int[] b = new int[3];

for(int i:b){System.out.println(i);}

 

总结:

Enhanced for Loop的语法:

for ( FormalParameter : Expression )
Statement

等价于原来的:

for ( Iterator<E> #i = Expression.iterator(); #i.hasNext(); ) {
FormalParameter = #i.next();
Statement

}

 

FormalParameter = Expression.iteraotor().next();

 

4. Enumerated Types

5.0开始,j2se支持枚举类型。简单的枚举使用如下:

public enum Color{RED,BLUE,GREEN;};

public static void main(String[] args){

for(Color c:Color.values()){

System.out.println(c);

}

}

输出为

RED

BLUE

GREEN

 

稍微复杂一点的使用,可以增加对枚举类型的定义:

public enum Color{RED(1),BLUE(5),GREEN(7);

private int value;

Color(int value){this.value = value;}

public int value(){return this.value;}

};

public static void main(String[] args){

for(Color c:Color.values()){

System.out.println(c);

System.out.println(c.value() == 1);

}

}

输出为:

RED

True

BLUE

false

GREEN

false

 

其中在枚举的声明当中的这部分内容:

private int value;

Color(int value){this.value = value;}

public int value(){return this.value;}

就等价与声明了一个Color类:

public class Color{

private int value;

Color(int value){this.value = value;}

public int value(){return this.value;}

}

 

还有就是,枚举也能用于switch结构当中,象

switch(c){

case RED:…

case BLUE:…

}

 

5. Static Import

以前,当我们要使用某个类当中的某个static变量,如BorderLayout.CENTER时,我们需要进行完整的书写,但通过使用Static Import,我们可以只书写CENTER即可,即:

import static java.awt.BorderLayout.* // 导入

 

getContentPane().add(new JPanel(),CENTER); // 使用

 

Static Import的使用,使得我们在不引入类的情况下,能只引用某个类的static变量

 

6. Formatted Output and Formatted Input

Formatted Output使得我们可以使用类Cprintf方法中的格式化变量,对输出进行格式化,如

System.out.printf(“%s %5d %n”,user,total);

 

7. Varargs

先看一个5.0当中的例子:

public class Test{

public Test(){}

 

public void out(String ...args){

for(String s:args){

System.out.println(s);

}

}

 

public static void main(String[] args){

Test t = new Test();

t.out("a","b","c");

}

}

可以注意到,在out方法的参数表当中,我们的参数声明是…args,这就是5.0引入的Varargs概念,即允许你一次传达多个参数,同样的效果如果需要在5.0之前实现的话,我们可能需要把方法的参数列表声明为一个数组,或集合,然后在调用该方法时,把参数封装到一个数组或者集合当中。即:

public void out(String[] args){}

out(new String[]{“a”,”b”,”c”});

 

8. 同步集合-Queue,BlockingQueue

J2SE 5.0里面添加了新的用于提高同步性能的集合类--QueueQueue是一个FIFO队列,她的作用主要是提高了并发访问性能,她与原来集合类当中的List的区别包括:

1. 她提供了一些新的方法,用于添加元素的offer(),用于删除元素的poll(),用于获取队首元素的peak()。这些操作与原来的add()remove()的区别在于,原有的add()remove()element()当所需操作失败的时候会抛出异常,而新的offer()poll()则不会,当队列不能容纳新元素时,offer()直接返回,当队列没有元素可取的时候,poll()操作,返回null

例子:

 

public class Test{

private ArrayBlockingQueue<Integer> list;

 

public Test(int capacity){

list = new ArrayBlockingQueue<Integer>(capacity);

}

 

public void add(int size){

for(int i=0;i<size;i++){

list.add(i);

output();

}

}

 

public void output(){

for(int i:list){

System.out.print(i+" ");

}

}

 

public static void main(String[] args){

Test t = new Test(2);

t.add(3);

}

}

 

往一个容量为2的队列里面添加3个元素,他的输出为

======= Start ===============================================

0

========================================= Stop ==============

 

======= Start ===============================================

0 1

========================================= Stop ==============

 

Exception in thread "main" java.lang.IllegalStateException: Queue full

at java.util.AbstractQueue.add(Unknown Source)

at Test.add(Test.java:14)

at Test.main(Test.java:32)

 

把上述代码修改为:

public void add(int size){

for(int i=0;i<size;i++){

list.offer(i);

output();

}

}

输出为:

======= Start ===============================================

0

========================================= Stop ==============

 

======= Start ===============================================

0 1

========================================= Stop ==============

 

======= Start ===============================================

0 1

========================================= Stop ==============

 

2. BlockingQueueQueue的一个子接口,她提供了新的用于阻塞的操作,take()put(),当队列没有空间,而线程欲通过put()往队列中添加元素时,线程会被阻塞。同理,当队列没有空间,而线程欲通过take()往队列中获取元素时,线程也会被阻塞。利用BlockingQueeu,我们可以很简单的实现生产者和消费者问题。

 

 

例子:

生产者:

public class Producer extends Thread{

 

private BlockingQueue queue;

private int count;

 

public Producer(BlockingQueue queue){