JDK1.5新特性:静态导入、可变参数、增强for循环、自动装箱拆箱(享元设计模式)、枚举、注解、泛型、

Java 5 新特性:

除本文中列出的新特性之外,新特性还有:注解和泛型。

注解注解的介绍

泛型泛型的介绍


1  静态导入

静态导入功能可以导入一个类中的所有静态成员。

静态导入功能导入类中的静态方法时,再调用此静态方法是就不用指定类名了。

比如System.out.println(); 静态导入System类中的所有静态成员后,

不用再指定类名,简化为 out.println(); 


静态导入比原先的导入更进了一步,以前导入包中的类,现在可以导入类中的方法。

 

但是,当类名重复时,需要制定具体的包名;当方法名重复时,需要指定具体的类名。

代码示例:

import java.util.*;
import static java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。
import static java.lang.System.*;//导入了System类中的所有静态成员(System类中全是静态的)。

class StaticImportDemo{
	public static void main(String[] args){
		int[] arr = {3,1,5};
		
	  //Arrays.sort(arr);
		sort(arr);    //已导入Arrays类的所有静态成员,不需再指定类名。
		
	  //int index = Arrays.binarySearch(arr,1);
		int index = binarySearch(arr,1); //已导入Arrays类的所有静态成员,不需再指定类名。
		
		//因为Object类和Arrays类中都有toString()方法,所以需指定所属类名。
		sop(Arrays.toString(arr));
		sop("index="+index);
	}
	
	public static void sop(Object obj){
		//因已导入System类的所有静态成员,所以省略了System。
		out.println(obj);
	}
}

2  可变参数

当方法的参数列表中同类型的参数个数不同时,以前使用方法的重载解决。

现在有了可变参数,就可以简单的解决这种情况。

 

可变参数格式:show( String str, Int... arr);  //以自定义的show方法举例。

可变参数特点:

      1,可变参数中是同类型的参数。

      2”...” 定义在变量类型和变量名之间,用来表示可变长度。

      3,使用时可以传递多个参数也可以不传递参数。

      4,☆一个方法只能有一个可变参数,并且可变参数必须位于参数列表的最后

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

 

可变参数其实就是一种数组参数的简写形式,不用每一次都手动的建立数组。

与数组参数不同的是:

      数组参数的长度是在方法定义时,就定义好的,长度固定。

      可变参数是在调用方法时,才根据传递的参数长度再创建数组。

 

代码示例:

import java.util.*;

class ParamMethodDemo{
	public static void main(String[] args){
		//show(3,4);
        
	 /* int[] arr = {3,4}; //虽然少定义了多个方法,但是每一次都要定义一个数组,作为实际参数。
		show(arr); /*
		show2(2,3,4,5,6);
		show2(2,3,4,5,6,7,8,2,12,35,9);  //不定义数组,直接传输数组,show的可变参数。
		
		show3("String",3,1,4,5,6,2);
		
	}
	
	public static void show(int[] arr){
		System.out.println(arr);
	}
	
	public static void show2(int... arr){ //“...”三个点表示可变参数。
		System.out.println(arr.length);
	}
	
	public static void show3(String str,int... arr){//可变参数必须定义在参数列表的最后面。
		System.out.println(str);
		System.out.println(arr.length);
	}
}

3  增强for循环

增强for循环格式:

for ( 数据类型 变量名 :被遍历的集合或者数组)

{ }

 

元素的数据类型,每个元素用变量存储,遍历集合中的元素。

对集合进行遍历,只能获取集合元素,但是不能对集合进行操作。

 

而迭代器除了遍历,还可以remove集合中的元素。如果是ListIterator,还可以在遍历过程中对集合进行增删改查的动作。

 

传统for循环和高级for循环有什么区别?

高级for循环有一个局限性,必须有被遍历的目标。

 

建议在遍历数组的时候,还是希望是用传统for,因为传统for可以定义脚标。

 

代码示例:

import java.util.*;

class ForEachDemo{
	public static void main(String[] args){
		ArrayList<String> al = new ArrayList<String>();
		
		al.add("abc01");
		al.add("abc02");
		al.add("abc03");
		
	 /* Iterator<String> it = al.iterator(); //迭代器
		while(it.hasNext()){
			System.out.println(it.next());
		} */
		
		for(String s : al){ //遍历al集合中所有元素,存储到变量s。
			System.out.println(s);
		}
		System.out.println(al);
		
		int[] arr = {3,5,11};
		for(int x=0; x<arr.length; x++){
			System.out.println(arr[x]);
		}
		for(int i : arr){
			System.out.println("i: "+i);
		}
		
		HashMap<Integer,String> hm = new HashMap<Integer,String>();
		hm.put(1,"a");
		hm.put(2,"b");
		hm.put(3,"c");
		
		Set<Integer> keySet = hm.keySet();
		for(Integer i : keySet){
			System.out.println(i+"::"+hm.get(i));
		}
		
	  //Set<Map.Entry<Integer,String>> entrySet = hm.entrySet();
	  //for(Map.Entry<Integer,String> me : entrySet)
		
		for(Map.Entry<Integer,String> me : hm.entrySet()){
			System.out.println(me.getKey()+"...."+me.getValue());
		}
	}
}

4  自动装箱拆箱与享元设计模式

JDK1.5中,引入了基本数据类型包装类的自动装箱、自动拆箱功能。

自动装箱,如:

Integer num = 2; //自动装箱

把一个基本类型的数据,自动装箱成一个Integer对象。

自动拆箱,如:

Integer num = 2;  //自动装箱
System.out.println(num + 3);  //自动拆箱

由于num为Integer对象,而3为int属于基本数据类型,必须把num自动拆箱成基本数据类型后,才能和3相加。

自动装箱拆箱中,涉及到了享元设计模式。

比如:

class AutoBoxDemo{
	public static void main(String[] args){
        //自动装箱:
		Integer iObj = 3;
        
		//自动拆箱:
        System. out.println(iObj + 12);
        //结果:15
            
        Integer i1 = 13;
        Integer i2 = 13;
        System. out.println(i1 == i2);
        //结果:true
        
        Integer i3 = 137;
        Integer i4 = 137;
        System. out.println(i3 == i4);
        //结果:false
    }
}

上面代码中,为什么一个结果为true,一个结果为false呢?

      如果一个整数大小在一个字节的取值之间,即 -128~127 之间,

      当这个整数被自动装箱包装成Integer对象时,

      JVM就会将这些值比较小的基本数据类型对象放入一个缓冲池中,以便于程序的其他部分复用这个对象。

  因为Java认为值很小的对象使用频率很高。

      这就是享元设计模式!

享元设计模式的思想:常常用的东西,存放到公共空间,大家分享,节省内存。

 

所以,值为13i1对象创建时被放入缓冲池,i2只是这个对象的另一个引用,所以 i1==i2 结果为true

而值为137i3对象,因为值大于了127,所以没有被放入缓冲池,i4时也是新创建的一个对象,而不是引用,所以 i3==i4 结果为false

 

5  枚举

举例说明枚举的作用:

      大家都知道一周只有7天,即星期一到星期日,

      如果用整数1-7分别表示星期一到星期日,但是有人却取值为00不是这一周的任何一天,这时就发生了意外。

枚举,就是让某个变量的取值只能是若干个固定值中的一个,否则,编译器就报错。

枚举可以让编译器在编译阶段就控制源程序中的非法输入,而普通变量无法在编译阶段达到这样一个功能。

 

5.1  用普通类实现枚举的功能

模拟枚举的步骤:

      1,私有化构造函数。

            私有化原因:外部不能创建这个类的对象,这样这个类的取值就固定了,只能是类中定义的对象。

      2,每一个枚举成员都要定义成全局静态常量(用public static final修饰)。

      3,定义若干个枚举成员公共的方法。

            可以是具体方法,直接定义了具体实现。

           也可以是抽象方法,由枚举成员以匿名内部类实现。不同的枚举成员有不同的实现。

 

代码示例:

/*
 *包含枚举成员共有方法的具体实现。
 **/
class WeekDay {
	//1,私有化构造方法
    private WeekDay(){}
	
	//2,每一个元素为全局静态常量,public static final ----枚举中的常量元素
    public static final WeekDay MON =new WeekDay();
    public static final WeekDay SUN =new WeekDay();
	
	//3,自定义的方法,包含具体实现
    public WeekDay nextDay(){
       if(this == MON)   //MON为枚举常量
           return SUN;
       return MON;
    }
/*
    缺点:如果枚举常量值非常多的时候,这个方法中会存在大量的if...else
*/
    public String toString(){
       return (this==SUN)? "SUN": "MON";
    }
}

/*
 *包含抽象方法时,每个枚举对象用匿名内部类实现:
 * */
abstract class WeekDay2 {
    //1,私有化构造方法
    private WeekDay2(){}
	
    // 采用匿名内部类实现抽象方法
    public static final WeekDay2 MON =new WeekDay2(){
       public WeekDay2 nextDay() {
           return SUN;
       }
       public String toString(){
           return "MON";
       }
    };
    public static final WeekDay2 SUN =new WeekDay2(){
       
       public WeekDay2 nextDay() {
           return MON;
       }
       public String toString(){
           return "SUN";
       }
    };
	
	//枚举成员的公共方法是抽象的,定义枚举时再具体实现
    public abstract WeekDay2 nextDay();
}

public class EnumDemo{
	public static void main(String[] args){
		WeekDay2 day = WeekDay2.SUN;  //枚举SUN是静态的,可直接使用
		System.out.println(day.nextDay());
	}
}

5.2  Java5中的枚举

JDK1.5中如何定义枚举?

使用 enum 关键字定义一个枚举类。

枚举是一种特殊的类,其中每个元素都是该类的一个实例对象。

枚举定义中,如果枚举中只有枚举元素没有其他成员,则最后一个枚举元素后面可以省略分号。

举例:

class TestEnum{
    public static void main(String[] args) {
       WeekDayEnum weekDay =WeekDayEnum.MON;
       System.out.println(weekDay);
    } 
}
enum WeekDayEnum {
     //枚举中只有枚举元素时,最后一个元素后可以不加分号
	SUN, MON, TUE, WED, THU, FRI, SAT 
}

枚举通常定义在其他类内部,可看作内部类:

class TestEnum{
    public static void main(String[] args) {
       WeekDayEnum weekDay =WeekDayEnum.MON;
       System.out.println(weekDay);
    } 
	
	//定义在其他类内部枚举,可以看做内部类:
	public enum WeekDayEnum {
        //枚举中只有枚举元素时,最后一个元素后可以不加分号
		SUN, MON, TUE, WED, THU, FRI, SAT 
	}
}

枚举关键字enum的好处:

使用enum关键字,就可以直接定义枚举类型的常量,代替用普通类实现枚举的3个步骤。

      1,省略了public static final修饰符的书写。

      2,省略私有化构造函数。

      3省略采用匿名内部类创建枚举常量的成员。

这些都封装在enum关键字中,大大简化了书写。

使用枚举关键字enum,可以很大程度简化枚举的书写。

 

5.3  带构造函数的枚举

枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。
枚举元素必须位于枚举体中的最开始部分,枚举元素列表的最后要有分号与其他成员分隔。

      也就是说,枚举成员常量位于构造函数等其他一切成员之前。

把枚举中的成员方法或变量等放在枚举元素的前面,编译器会报告错误。

带构造方法的枚举:

      1构造方法必须定义成私有的

      2如果有多个构造方法,将根据枚举元素创建时所带的参数决定选择哪个构造方法创建对象。
            枚举元素MONMON() 的效果一样,都是调用默认的构造方法。

      3,枚举是静态常量,所以枚举类一加载到内存时,相应的枚举成员就会调用构造函数。

 

代码示例:

public class EnumTest {

    public static void main(String[] args) {
         WeekDay day = WeekDay.FRI;
    }
      
    public enum WeekDay{
        SUN(1),MON (),TUE, WED,THI ,FRI,SAT;
        
		private WeekDay(){
            System. out.println("first" );
        }
            
        private WeekDay(int value){
            System. out.println("second" );
        }
    }
}

5.4  实现抽象方法的枚举

定义枚举TrafficLamp
实现抽象的nextTrafficLamp方法:每个元素分别是由枚举类的子类来生成的实例对象,这些子类采用类似内部类的方式进行定义。
增加上表示时间的构造方法。

枚举只有一个成员时,就可以作为一种单例的实现方式。

 

代码示例:

public class EnumDemo4 {
    public static void main(String[] args) {
        TrafficLamp lamp = TrafficLamp.RED;
        System. out.println(lamp.nextLamp());
        //结果:GREEN
    }
      
    public enum TrafficLamp{
		//匿名内部类的形式实现抽象方法。
        RED(30) {
            public TrafficLamp nextLamp() {
                return GREEN ;
            }
        }, GREEN(45) {
            public TrafficLamp nextLamp() {
                return YELLOW ;
            }
        }, YELLOW(5) {
            public TrafficLamp nextLamp() {
                return RED ;
            }
        };
        
        private int time;
        private TrafficLamp(int time){ //构造方法
            this.time = time;
        }
        public abstract TrafficLamp nextLamp(); //抽象方法
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值