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)的变量,如int,float等,在添加到Collection当中时,需要使用他们对应的封装类Integer,Float等,如:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0, new Integer(42));
int total = (list.get(0)).intValue();
在5.0当中,通过使用Autoboxing和Auto-Unboxing我们就不再需要显式的使用这些封装类了。
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0, 42);
int total = list.get(0);
3. Enhanced for
一般来说,当我们需要对数组和集合进行遍历时,我们需要这样做:
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.0的Enhanced 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使得我们可以使用类C的printf方法中的格式化变量,对输出进行格式化,如
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里面添加了新的用于提高同步性能的集合类--Queue。Queue是一个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. BlockingQueue是Queue的一个子接口,她提供了新的用于阻塞的操作,take()和put(),当队列没有空间,而线程欲通过put()往队列中添加元素时,线程会被阻塞。同理,当队列没有空间,而线程欲通过take()往队列中获取元素时,线程也会被阻塞。利用BlockingQueeu,我们可以很简单的实现生产者和消费者问题。
例子:
生产者:
public class Producer extends Thread{
private BlockingQueue queue;
private int count;
public Producer(BlockingQueue queue){