jdk5.0的新特性

jdk的版本在1.4后变化很大,所以叫jdk5.0

下面是总结jdk5.0的新特性:

 

(1)泛型(***)

 泛型简介

  泛型是J2SE 5.0最重要的特性。他们让你写一个type(类或接口)和创建一个实例通过传递一个或多个引用类型。这个实例受限于只能作用于这些类型。比如,在java 5,java.util.List 已经被泛化。当建立一个list对象时,你通过传递一个java类型建立一个List实例,此list实例只能作用于所传递的类型。这意味着如果你传递一个String ,此List实例只能拥有String对象;如果你传递一个Integer,此实例只能存贮Integer对象。除了创建参数化的类型,你还能创建参数化的函数。
     泛型的第一个好处是编译时的严格类型检查。这是集合框架最重要的特点。此外,泛型消除了绝大多数的类型转换。在JDK 5.0之前,当你使用集合框架时,你不得不进行类型转换。
     本文将教你如何操作泛型。它的第一部分是“没有泛型的日子”,先让我们回忆老版本JDK的不便。然后,举一些泛型的例子。在讨论完语法以及有界泛型的使用之后,文章最后一章将解释如何写泛型。

没有泛型的日子
     所有的java类都源自java.lang.Object,这意味着所有的JAVA对象能转换成Object。因此,在之前的JDK的版本中,很多集合框架的函数接受一个Object参数。所以,collections是一个能持有任何对象的多用途工具,但带来了不良的后果。

     举个简单的例子,在JDK 5.0的之前版本中,类List的函数add接受一个Object参数:


public boolean add(java.lang.Object element)


        所以你能传递任何类型给add。这是故意这么设计的。否则,它只能传递某种特定的对象,这样就会出现各种List类型,如,StringList, EmployeeList, AddressList等。
     add通过Object传递能带来好处,现在我们考虑get函数(返回List中的一个元素).如下是JDK 5之前版本的定义:

 

public java.lang.Object get(int index) throws IndexOutOfBoundsException


get返回一个Object.不幸的事情从此开始了.假如你储存了两个String对象在一个List中:

 

List stringList1 = new ArrayList();stringList1.add("Java 5");stringList1.add("with generics");


当你想从stringList1取得一个元素时,你得到了一个Object.为了操作原来的类型元素,你不得不把它转换为String。

 

String s1 = (String) stringList1.get(0);


但是,假如你曾经把一个非String对象加入stringList1中,上面的代码会抛出一个ClassCastException. 有了泛型,你能创建一个单一用途的List实例.比如,你能创建一个只接受String对象的List实例,另外一个实例只能接受Employee对象.这同样适用于集合框架中的其他类型.


泛型入门

   像一个函数能接受参数一样,一个泛型也能接受参数.这就是一个泛型经常被称为一个参数化类型的原因.但是不像函数用()传递参数,泛型是用<>传递参数的.声明一个泛型和声明一个普通类没有什么区别,只不过你把泛型的变量放在<>中.
     比如,在JDK 5中,你可以这样声明一个java.util.List : List<E> myList;
E 称为类型变量.意味着一个变量将被一个类型替代.替代类型变量的值将被当作参数或返回类型.对于List接口来说,当一个实例被创建以后,E 将被当作一个add或别的函数的参数.E 也会使get或别的参数的返回值.下面是add和get的定义:

 

boolean add<E o>E get(int index)

 

泛型在List、Set、Map上的应用及三种类型的遍历

package com.yangying.fanxing;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class FanListMapSet {

    public static void main(String[] args) {
        
        //useArrayList();
        //useSet();
        
        //useMap();
        
    }




    public static void useMap() {
        Map<String,String> map = new HashMap<String,String>();
        map.put("name", "yangying");
        map.put("age", "24");
        map.put("sex", "female");
        
        //遍历map集合有两种方法
        Set<String> keySet = map.keySet();
        
        for (String key : keySet) {
            String value = map.get(key);
            System.out.println(key + "=" + value);
        }
        System.out.println("=====================");
        
        //得到key,value的关系
        Set<Entry<String,String>> set = map.entrySet();
        Iterator it = set.iterator();
        while(it.hasNext()){
            System.out.println(it.next().toString());
        }
    }

    
    
    
    //2.泛型在Set上使用
    public static void useSet() {
        Set<String> set = new HashSet<String>();
        set.add("aaa");
        set.add("bbb");
        set.add("ccc");

        
        //遍历有两种方法
        //1.增强for循环
        for (String str : set) {
            System.out.print(str);
        }
        System.out.println("\n=====================");
        
        //2.迭代器
        Iterator it = set.iterator();
        while(it.hasNext()){
            System.out.print(it.next());
        }
    }
    
    
    // 1.泛型在ArrayList使用
    public static void useArrayList() {
        //ArrayList list = new ArrayList();
        List<Integer> list = new ArrayList<Integer>();
        list.add(3);
        list.add(4);
        list.add(5);
        
        //遍历有三种方法
        //1.普通for循环
        for(int i=0; i<list.size(); i++){
            System.out.print(list.get(i));
        }        
        System.out.println("\n==============================");
        
        //增强for循环
        for(Integer n:list){
            System.out.print(n);
        }        
        System.out.println("\n==============================");
        
        //迭代器
        Iterator<Integer> it1 = list.iterator();
        while(it1.hasNext()){
            System.out.print(it1.next());
        }
    }

}

 

(2)枚举

 

(3)增强for循环(***)

 

在上面这个例子 增强型的for循环 和普通for循环一样
增强型的for循环 优点主要体现在集合中,随便举个例子
比如对 set 的遍历
一般是迭代遍历:
Set<String> set = new HashSet<String>();
Iterator<String> it = set.iterator();
while (it.hasNext()) {
String str = it.next();
System.out.println(str);
}
for循环遍历:
for (String str : set) {
System.out.println(str);
}
是不是简单些?

优点还体现在泛型 假如 set中存放的是Object

Set<Object> set = new HashSet<Object>();
for循环遍历:
for (Object obj: set) {
if(obj instanceof Integer){
int aa= (Integer)obj;
}else if(obj instanceof String){
String aa = (String)obj
}
........
}
如果你用Iterator遍历,那就晕了
map list 也一样

唯一的缺点就是 在遍历 集合过程中,不能对集合本身进行操作
for (String str : set) {
set.remove(str);//错误!
}


(4)静态导入

 

(5)自动拆装箱(***)

 

  基本数据类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。 

  一般我们要创建一个类的对象实例的时候,我们会这样:

   Class a = new Class(parameter);

   当我们创建一个Integer对象时,却可以这样:

   Integer i = 100; (注意:不是 int i = 100; )

  实际上,执行上面那句代码的时候,系统为我们执行了:Integer i = Integer.valueOf(100); (感谢@黑面馒头 和 @MayDayIT 的提醒)

  此即基本数据类型的自动装箱功能。

(6)可变参数(***)

 

  Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理。注意:可变参数必须位于最后一项。当可变参数个数多余一个时,必将有一个不是最后一项,所以只支持有一个可变参数。因为参数个数不定,所以当其后边还有相同类型参数时,java无法区分传入的参数属于前一个可变参数还是后边的参数,所以只能让可变参数位于最后一项。

可变参数的特点:

(1)、只能出现在参数列表的最后; 

(2)、...位于变量类型和变量名之间,前后有无空格都可以;

(3)、调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中一数组的形式访问可变参数。

public class Varable {
 public static void main(String [] args){
  System.out.println(add(2,3));
  System.out.println(add(2,3,5));
 }
 public static int add(int x,int ...args){
  int sum=x;
  for(int i=0;i<args.length;i++){
   sum+=args[i];
  }
  return sum;
 }
}

 

posted on 2015-11-24 09:15  wawa11  阅读(239)  评论(0编辑  收藏  举报

导航